home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / db / rdbms71 / cdemo1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-10  |  11.3 KB  |  413 lines

  1. #ifdef RCSID
  2.    "$Header: cdemo1.c 7010300.1 94/02/24 18:40:42 snataraj Generic<base> $ ";
  3. #endif /* RCSID */
  4.  
  5. /* Copyright (c) 1991 by Oracle Corporation */
  6. /*
  7.    NAME
  8.      cdemo1.c - C Demo Program
  9.    MODIFIED   (MM/DD/YY)
  10.     emendez    02/02/94 -  Fix for bug 157576
  11.     gdoherty   01/31/94 -  make oci header inclusion for ansi or k+r adaptive
  12.     tssmith    03/29/93 -  Changing to non-ANSI function defs and decls
  13.     lfeng      01/13/93 -  fix non-portable fflush 
  14.     rkooi2     11/27/92 -  Datatype changes to agree with ocidef.h 
  15.     lfeng      11/20/92 -  add more portability modes 
  16.     rkooi2     11/04/92 -  Fix comp errors 
  17.     rkooi2     10/27/92 -  More portability mods 
  18.     rkooi2     10/18/92 -  Changes to make it portable 
  19.     sjain      03/16/92 -  Creation 
  20. */
  21. /* 
  22.  *      -- cdemo1.c --
  23.  *  An example program which adds new employee
  24.  *  records to the personnel data base.  Checking
  25.  *  is done to insure the integrity of the data base.
  26.  *  The employee numbers are automatically selected using
  27.  *  the current maximum employee number as the start.
  28.  *  
  29.  *  The program queries the user for data as follows:
  30.  *   
  31.  *  Enter employee name:
  32.  *  Enter employee job:
  33.  *  Enter employee salary:
  34.  *  Enter employee dept:
  35.  *   
  36.  *  The program terminates if return key (CR) is entered
  37.  *  when the employee name is requested.
  38.  *   
  39.  *  If the record is successfully inserted, the following
  40.  *  is printed:
  41.  *   
  42.  *  "ename" added to department "dname" as employee # "empno"
  43.  */
  44.  
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <ctype.h>
  48. #include <string.h>
  49.  
  50.  
  51. #include <oratypes.h>
  52. /* LDA and CDA struct declarations */
  53. #include <ocidfn.h>
  54. #ifdef __STDC__
  55. #include <ociapr.h>
  56. #else
  57. #include <ocikpr.h>
  58. #endif
  59. /* demo constants and structs */
  60. #include <ocidem.h>
  61.  
  62. /* oparse flags */
  63. #define  DEFER_PARSE        1
  64. #define  NATIVE             1
  65. #define  VERSION_7          2
  66.  
  67.  
  68. text *username = (text *) "SCOTT";
  69. text *password = (text *) "TIGER";  
  70.  
  71. /* Define SQL statements to be used in program. */
  72. text *insert = (text *) "INSERT INTO emp(empno, ename, job, sal, deptno)\
  73.     VALUES (:empno, :ename, :job, :sal, :deptno)";
  74. text *seldept = (text *) "SELECT dname FROM dept WHERE deptno = :1";
  75. text *maxemp = (text *) "SELECT NVL(MAX(empno), 0) FROM emp";
  76. text *selemp = (text *) "SELECT ename, job FROM emp";
  77.  
  78. /* Define an LDA, a HDA,  and two cursors. */
  79. Lda_Def lda;
  80. ub1     hda[HDA_SIZE];
  81. Cda_Def cda1;
  82. Cda_Def cda2;
  83.  
  84.  
  85. void err_report();
  86.  
  87.  
  88.  
  89. main()
  90. {
  91.     sword empno, sal, deptno;
  92.     sb4 len, len2, dsize, dsize2;
  93.     sb4   enamelen, joblen, deptlen;
  94.     sb2   sal_ind, job_ind;
  95.     sb2   db_type, db2_type;  
  96.     sb1   name_buf[20], name2_buf[20]; 
  97.     text  *cp, *ename, *job, *dept;
  98.  
  99. /* 
  100.  *  Connect to ORACLE and open two cursors.
  101.  *  Exit on any error.
  102.  */
  103.     if (orlon(&lda, hda, username, -1, password, -1, 0))
  104.     {
  105.         err_report(&lda);
  106.         exit(EXIT_FAILURE);
  107.     }
  108.     printf("Connected to ORACLE as %s\n", username);
  109.  
  110.     if (oopen(&cda1, &lda, (text *) 0, -1, -1, (text *) 0, -1))
  111.     {
  112.         err_report(&cda1);
  113.         do_exit(EXIT_FAILURE);
  114.     }
  115.     if (oopen(&cda2, &lda, (text *) 0, -1, -1, (text *) 0, -1))
  116.     {
  117.         err_report(&cda2);
  118.         do_exit(EXIT_FAILURE);
  119.     }
  120.  
  121.     /* Turn off auto-commit. Default is off, however. */
  122.     if (ocof(&lda))
  123.     {
  124.         err_report(&lda);
  125.         do_exit(EXIT_FAILURE);
  126.     }
  127.  
  128.     /* Retrieve the current maximum employee number. */
  129.     if (oparse(&cda1, maxemp, (sb4) -1, DEFER_PARSE,
  130.                (ub4) VERSION_7))
  131.     {
  132.         err_report(&cda1);
  133.         do_exit(EXIT_FAILURE);
  134.     }
  135.     if (odefin(&cda1, 1, (ub1 *) &empno, (sword) sizeof(sword),
  136.                (sword) INT_TYPE,
  137.                (sword) -1, (sb2 *) 0, (text *) 0, -1, -1,
  138.                (ub2 *) 0, (ub2 *) 0))
  139.     {
  140.         err_report(&cda1);
  141.         do_exit(EXIT_FAILURE);
  142.     }
  143.     if (oexfet(&cda1, (ub4) 1, FALSE, FALSE))
  144.     {
  145.         if (cda1.rc == NO_DATA_FOUND)
  146.             empno = 10;
  147.         else
  148.         {
  149.             err_report(&cda1);
  150.             do_exit(EXIT_FAILURE);
  151.         }
  152.     }
  153.  
  154.     /*  Describe the columns in the select-list
  155.         of "selemp" to determine the max length of
  156.         the employee name and job title.
  157.      */
  158.     if (oparse(&cda1, selemp, (sb4) -1, FALSE, (ub4) VERSION_7))
  159.     {
  160.         err_report(&cda1);
  161.         do_exit(EXIT_FAILURE);
  162.     }
  163.  
  164.     len = sizeof(name_buf); len2 = sizeof (name2_buf);
  165.     if (odescr(&cda1, 1, &enamelen,
  166.                (sb2 *) &db_type, name_buf, (sb4 *) &len,
  167.                (sb4*) &dsize, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0) ||
  168.         odescr(&cda1, 2, &joblen,
  169.                (sb2 *) &db_type, name2_buf, (sb4 *) &len2,
  170.                (sb4 *) &dsize2, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0))
  171.     {
  172.         err_report(&cda1);
  173.         do_exit(EXIT_FAILURE);
  174.     }
  175.  
  176.     /* Parse the INSERT statement. */
  177.     if (oparse(&cda1, insert, (sb4) -1, FALSE, (ub4) VERSION_7))
  178.     {
  179.         err_report(&cda1);
  180.         do_exit(EXIT_FAILURE);
  181.     }
  182.  
  183.     /* Parse the SELDEPT statement. */
  184.     if (oparse(&cda2, seldept, (sb4) -1, FALSE, (ub4) VERSION_7))
  185.     {
  186.         err_report(&cda2);
  187.         do_exit(EXIT_FAILURE);
  188.     }
  189.  
  190.     /*  Allocate output buffers. Allow for \n and '\0'. */
  191.     ename = (text *) malloc((int) enamelen + 2);
  192.     job   = (text *) malloc((int) joblen + 2);
  193.  
  194.     /*  Bind the placeholders in the INSERT statement. */
  195.     if (obndrv(&cda1, (text *) ":ENAME", -1, (ub1 *) ename,
  196.                (sword) enamelen+1, STRING_TYPE, -1, (sb2 *) 0,
  197.                (text *) 0, -1, -1) ||
  198.         obndrv(&cda1, (text *) ":JOB", -1, (ub1 *) job, (sword) joblen+1,
  199.                STRING_TYPE, -1, &job_ind, (text *) 0, -1, -1) ||
  200.         obndrv(&cda1, (text *) ":SAL", -1, (ub1 *) &sal, (sword) sizeof (sal),
  201.                INT_TYPE, -1, &sal_ind, (text *) 0, -1, -1) ||
  202.         obndrv(&cda1, (text *) ":DEPTNO",-1, (ub1 *) &deptno,
  203.                (sword) sizeof (deptno), INT_TYPE, -1,
  204.                (sb2 *) 0, (text *) 0, -1, -1) ||
  205.         obndrv(&cda1, (text *) ":EMPNO", -1, (ub1 *) &empno,
  206.                (sword) sizeof (empno), INT_TYPE, -1,
  207.                (sb2 *) 0, (text *) 0, -1, -1)) 
  208.     {
  209.         err_report(&cda1);
  210.         do_exit(EXIT_FAILURE);
  211.     }
  212.  
  213.     /*  Bind the placeholder in the "seldept" statement. */
  214.     if (obndrn(&cda2,
  215.                1,
  216.                (ub1 *) &deptno,
  217.                (sword) sizeof(deptno),
  218.                INT_TYPE,
  219.                -1,
  220.                (sb2 *) 0,
  221.                (text *) 0,
  222.                -1,
  223.                -1))
  224.     {
  225.         err_report(&cda2);
  226.         do_exit(EXIT_FAILURE);
  227.     }  
  228.  
  229.     /*  Describe the select-list field "dname". */
  230.     len = sizeof (name_buf);
  231.     if (odescr(&cda2, 1, (sb4 *) &deptlen, &db_type,
  232.                name_buf, &len, &dsize, (sb2 *) 0,
  233.                (sb2 *) 0, (sb2 *) 0))
  234.     {
  235.         err_report(&cda2);
  236.         do_exit(EXIT_FAILURE);
  237.     }
  238.  
  239. /*  Allocate the dept buffer now that you have length. */
  240.     dept = (text *) malloc((int) deptlen + 1);
  241.  
  242.     /*  Define the output variable for the select-list. */
  243.     if (odefin(&cda2,
  244.                1,
  245.                (ub1 *) dept,
  246.                (sword) deptlen+1,
  247.                STRING_TYPE,
  248.                -1,
  249.                (sb2 *) 0,
  250.                (text *) 0,
  251.                -1,
  252.                -1,
  253.                (ub2 *) 0,
  254.                (ub2 *) 0))
  255.     {
  256.         err_report(&cda2);
  257.         do_exit(EXIT_FAILURE);
  258.     }
  259.  
  260.     for (;;)
  261.     {
  262.         /* Prompt for employee name.  Break on no name. */
  263.         printf("\nEnter employee name (or CR to EXIT): ");
  264.         fgets((char *) ename, (int) enamelen+1, stdin);
  265.         cp = (text *) strchr((char *) ename, '\n');
  266.         if (cp == ename)
  267.         {
  268.             printf("Exiting... ");
  269.             do_exit(EXIT_SUCCESS);
  270.         }
  271.         if (cp)
  272.             *cp = '\0';
  273.         else
  274.       {
  275.             printf("Employee name may be truncated.\n");
  276.         myfflush();
  277.       }
  278.         /*  Prompt for the employee's job and salary. */
  279.         printf("Enter employee job: ");
  280.         job_ind = 0;
  281.         fgets((char *) job, (int) joblen + 1, stdin);
  282.         cp = (text *) strchr((char *) job, '\n');
  283.         if (cp == job)
  284.         {
  285.             job_ind = -1;            /* make it NULL in table */
  286.             printf("Job is NULL.\n");/* using indicator variable */
  287.         }
  288.         else if (cp == 0)
  289.       {
  290.             printf("Job description may be truncated.\n");
  291.         myfflush();
  292.       }
  293.         else
  294.             *cp = '\0';
  295.  
  296.         printf("Enter employee salary: ");
  297.         scanf("%d", &sal);
  298.     myfflush();
  299.         sal_ind = (sal <= 0) ? -2 : 0;  /* set indicator variable */
  300.  
  301.         /*
  302.          *  Prompt for the employee's department number, and verify
  303.          *  that the entered department number is valid
  304.          *  by executing and fetching.
  305.          */
  306.         do
  307.         {
  308.             printf("Enter employee dept: ");
  309.             scanf("%d", &deptno);
  310.         myfflush();
  311.             if (oexec(&cda2) ||
  312.                     (ofetch(&cda2) && (cda2.rc != NO_DATA_FOUND)))
  313.             {
  314.                 err_report(&cda2);
  315.                 do_exit(EXIT_FAILURE);
  316.             }  
  317.             if (cda2.rc == NO_DATA_FOUND)
  318.                 printf("The dept you entered doesn't exist.\n");
  319.         } while (cda2.rc == NO_DATA_FOUND);
  320.  
  321.         /*
  322.          *  Increment empno by 10, and execute the INSERT
  323.          *  statement. If the return code is 1 (duplicate
  324.          *  value in index), then generate the next
  325.          *  employee number.
  326.          */
  327.         empno += 10;
  328.         if (oexec(&cda1) && cda1.rc != 1)
  329.         {
  330.             err_report(&cda1);
  331.             do_exit(EXIT_FAILURE);
  332.         }
  333.         while (cda1.rc == 1)
  334.         {
  335.             empno += 10;
  336.             if (oexec(&cda1) && cda1.rc != 1)
  337.             {
  338.                 err_report(&cda1);
  339.                 do_exit(EXIT_FAILURE);
  340.             }
  341.         }  /* end for (;;) */
  342.  
  343. /* Commit the change. */
  344.         if (ocom(&lda))
  345.         {
  346.             err_report(&lda);
  347.             do_exit(EXIT_FAILURE);
  348.         }
  349.         printf(
  350.         "\n\n%s added to the %s department as employee number %d\n",
  351.                  ename, dept, empno);
  352.     }
  353.     do_exit(EXIT_SUCCESS);
  354.  
  355. }
  356.  
  357.  
  358. void
  359. err_report(cursor)
  360.     Cda_Def *cursor;
  361. {
  362.     sword n;
  363.     text msg[512];
  364.  
  365.     printf("\n-- ORACLE error--\n");
  366.     printf("\n");
  367.     n = oerhms(&lda, cursor->rc, msg, (sword) sizeof msg);
  368.     fprintf(stderr, "%s\n", msg);
  369.     if (cursor->fc > 0)
  370.         fprintf(stderr, "Processing OCI function %s",
  371.             oci_func_tab[cursor->fc]);
  372. }
  373.  
  374.  
  375. /*
  376.  *  Exit program with an exit code.
  377.  */
  378. do_exit(exit_code)
  379.     sword exit_code;
  380. {
  381.     sword error = 0;
  382.  
  383.     if (oclose(&cda1))
  384.     {
  385.         fprintf(stderr, "Error closing cursor 1.\n");
  386.         error++;
  387.     }
  388.     if (oclose(&cda2))
  389.     {
  390.         fprintf(stderr, "Error closing cursor 2.\n");
  391.         error++;
  392.     }
  393.     if (ologof(&lda))
  394.     {
  395.         fprintf(stderr, "Error on disconnect.\n");
  396.         error++;
  397.     }
  398.     if (error == 0 && exit_code == EXIT_SUCCESS)
  399.         printf ("\nG'day\n");
  400.  
  401.     exit(exit_code);
  402. }
  403.  
  404.  
  405. myfflush()
  406. {
  407.   eb1 buf[50];
  408.  
  409.   fgets((char *) buf, 50, stdin);
  410. }
  411.  
  412.  
  413.