home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a524 / 42.ddi / demo / sample.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-04  |  9.8 KB  |  371 lines

  1. #ifdef RCSID
  2. static char *RCSid = 
  3.    "$Header: sample.c,v 6.2 89/05/25 13:03:40 ksriniva Exp $ sample.c Copyr (c) 1986 Oracle";
  4. #endif /* RCSID */
  5.  
  6. /*
  7. **
  8. ** sample  is a simple example program which adds new employee
  9. **       records  to the  personnel  data base.  Checking is
  10. **       done to insure the integrity of the data base.  The
  11. **       employee numbers  are automatically    selected using
  12. **       the    current maximum  employee number as the start.
  13. **       If  any  employee  number  is  a  duplicate,  it is
  14. **       skipped.  The  program queries the user for data as
  15. **       follows:
  16. **           Enter employee name:
  17. **           Enter employee job:
  18. **           Enter employee salary:
  19. **           Enter employee dept:
  20. **
  21. **       The program terminates if EOF (end of file) or a null
  22. **       string (<return> key) is entered when the employee name
  23. **       is requested.
  24. **
  25. **       If a record is successfully inserted, the following
  26. **       is printed:
  27. **
  28. **       ename added to department dname as employee # nnnnnn
  29. **
  30. **       The new employee number is 10 more than the highest
  31. **       previous employee number.
  32. **
  33. ** UNIX COMPILING/LINKING INSTRUCTIONS:
  34. **         $ make -f proc.mk sample
  35. */
  36.  
  37. #include <stdio.h>
  38. #include <ctype.h>
  39. /*
  40. ** DEFINE THE c VERSION OF THE CURSOR (FOR 32 BIT MACHINES)
  41. */
  42. struct csrdef
  43. {
  44.    short      csrrc;                  /* return code */
  45.    short      csrft;                /* function type */
  46.    unsigned long  csrrpc;             /* rows processed count */
  47.    short      csrpeo;               /* parse error offset */
  48.    unsigned char  csrfc;                /* function code */
  49.    unsigned char  csrfil;                      /* filler  */
  50.    unsigned short csrarc;                /* reserved, private */
  51.    unsigned char  csrwrn;                /* warning flags */
  52.    unsigned char  csrflg;                  /* error flags */
  53.    /*             *** Operating system dependent ***          */
  54.    unsigned int   csrcn;                /* cursor number */
  55.    struct {                          /* rowid structure */
  56.      struct {
  57.     unsigned long    tidtrba;       /* rba of first blockof table */
  58.     unsigned short    tidpid;         /* partition id of table */
  59.     unsigned char    tidtbl;             /* table id of table */
  60.     }        ridtid;
  61.      unsigned long   ridbrba;                 /* rba of datablock */
  62.      unsigned short  ridsqn;          /* sequence number of row in block */
  63.      } csrrid;
  64.    unsigned int   csrose;              /* os dependent error code */
  65.    unsigned char  csrchk;                   /* check byte */
  66.    unsigned char  crsfill[26];               /* private, reserved fill */
  67. };
  68. #define UCP(x) ((unsigned char *)(x))
  69.  
  70. char *uid = "scott/tiger";                          /* username/password */
  71. char *insert = "INSERT INTO EMP(EMPNO, ENAME, JOB, SAL, DEPTNO) VALUES \
  72.         (:EMPNO, :ENAME, :JOB, :SAL, :DEPTNO)";
  73. char *cselect = "SELECT DNAME FROM DEPT WHERE DEPTNO=:1";
  74. char *maxemp = "SELECT NVL(MAX(EMPNO), 0) + 10 FROM EMP";
  75. char *selemp = "SELECT ENAME, JOB FROM EMP";     /* find ename, job size */
  76.  
  77.  
  78. main()
  79. {
  80.    int      empno, sal, deptno;     /* employee number, salary, dept number */
  81.    int    tmpc;
  82.    struct csrdef lda;                         /* lda area */
  83.    struct csrdef curs[2];                  /* and two cursors */
  84.    char   hst[256];                      /* Host definition */
  85.    char   *ename, *job, *dept;           /* employee name,job and dept */
  86.    short  enamelmax, enamel, joblmax, jobl, deptl;
  87.    char   *malloc();
  88.  
  89. #define LDA &lda
  90. #define C0  (&curs[0])
  91. #define C1  (&curs[1])
  92. #define HST hst
  93. #define DUPLICATE_VALUE -9            /* HLI interface return code */
  94. #define INT 3                    /* HLI integer type code */
  95. #define CHRSTR 5              /* HLI null terminated string type */
  96. /*
  97. ** LOGON TO ORACLE, OPEN TWO CURSORS.  NOTE: IN MOST SITUATIONS,
  98. ** THIS SIMPLE PROGRAM EXITS IF ANY ERRORS OCCUR.
  99. */
  100.    if (orlon(LDA, HST, uid, -1, (char *)0, -1, -1))
  101.    {
  102.       errlda(LDA, "orlon");
  103.       goto errexit;
  104.    }
  105.  
  106.    if (oopen(C0, LDA, (char *)0, -1, -1, (char *)0, -1))
  107.    {
  108.       errrpt(C0);
  109.       goto errexit;
  110.    }
  111.  
  112.    if (oopen(C1, LDA, (char *)0, -1, -1, (char *)0, -1))
  113.    {
  114.       errrpt(C1);
  115.       goto errexit;
  116.    }
  117.  
  118. /*
  119. ** TURN OFF AUTO-COMMIT.  NOTE: THE DEFAULT IF OFF, SO THIS COULD
  120. ** BE OMMITTED.
  121. */
  122.    if (ocof(LDA))
  123.    {
  124.       errlda(LDA, "ocof");
  125.       goto errexit;
  126.    }
  127. /*
  128. ** RETRIEVE THE CURRENT MAXIMUM EMPLOYEE NUMBER
  129. */
  130.    if (osql3(C0, maxemp, -1)
  131.        || odefin(C0, 1, UCP(&empno), sizeof(empno),
  132.       INT, -1, (short *)0, (char *)0, -1, -1, (short *)0, (short *)0)
  133.        || oexec(C0)
  134.        || ofetch(C0))
  135.    {
  136.       errrpt(C0);
  137.       goto errexit;
  138.    }
  139.  
  140. /*
  141. ** DESCRIBE THE COLUMNS TO DETERMINE THE MAX LENGTH OF
  142. ** THE EMPLOYEE NAME, JOB TITLE.
  143. */
  144.    if (osql3(C0, selemp, -1)
  145.        || odsc(C0, 1, &enamelmax, (short *)0, (short *)0, (short *)0,
  146.            (char *)0, (short *)0, (short *)0)
  147.        || odsc(C0, 2, &joblmax,   (short *)0, (short *)0, (short *)0,
  148.            (char *)0, (short *)0, (short *)0) )
  149.    {
  150.       errrpt(C0);
  151.       goto errexit;
  152.    }
  153.  
  154.    job     = malloc(joblmax+1);           /* don't forget room for null */
  155.    ename = malloc(enamelmax+1);
  156.  
  157. /*
  158. ** PARSE THE INSERT AND SELECT STATEMENTS
  159. ** DESCRIBE dname SO THAT WE CAN ALLOCATE SPACE
  160. ** THEN DEFINE dept
  161. */
  162.    if (osql3(C0, insert, -1))
  163.    {
  164.       errrpt(C0);
  165.       goto errexit;
  166.    }
  167.  
  168.    if (osql3(C1, cselect, -1)
  169.        || odsc(C1, 1, &deptl, (short *)0, (short *)0, (short *)0,
  170.         (char *)0, (short *)0, (short *)0)
  171.        || odefin(C1, 1, dept = malloc(deptl+1) , deptl+1, CHRSTR,
  172.         -1, (short *)0, (char *)0, -1, -1, (short *)0, (short *)0) )
  173.    {
  174.       errrpt(C1);
  175.       goto errexit;
  176.    }
  177.  
  178. /*
  179. ** BIND SQL SUBSTITUTION VARIABLE VALUES USING BIND BY REFERENCE
  180. ** STATEMENTS.
  181. */
  182.  
  183.    if (   obndrv(C0, ":ENAME", -1, ename, (int)enamelmax+1, CHRSTR,
  184.          -1, (short *)0, (char *)0, -1, -1)
  185.        || obndrv(C0, ":JOB", -1, job, (int)joblmax+1, CHRSTR,
  186.          -1, (short *)0, (char *)0, -1, -1)
  187.        || obndrv(C0, ":SAL", -1, UCP(&sal), sizeof(sal),
  188.          INT, -1, (short *)0, (char *)0, -1, -1)
  189.        || obndrv(C0, ":DEPTNO",-1, UCP(&deptno), sizeof(deptno),
  190.          INT, -1, (short *)0, (char *)0, -1, -1)
  191.        || obndrv(C0, ":EMPNO", -1, UCP(&empno),  sizeof(empno),
  192.          INT, -1, (short *)0, (char *)0, -1, -1) )
  193.    {
  194.       errrpt(C0);
  195.       goto errexit;
  196.    }
  197.  
  198. /*
  199. ** READ THE USER'S INPUT FROM stdin.  IF THE EMPLOYEE NAME IS
  200. ** NOT ENTERED, THEN EXIT.  VERIFY THAT THE ENTERED DEPARTMENT
  201. ** NUMBER IS VALID AND ECHO THE DEPARTMENT'S NAME WHEN DISPLAYING
  202. ** THE NEW ROW.
  203. */
  204.  
  205.    for ( ; ; ) {
  206.       enamel = asks("Enter employee name  : ",ename,(int)enamelmax+1);
  207.       if ( enamel == enamelmax && ename[enamel] != '\n' ) {
  208.          printf("Name too long; truncated to \"%s\"\n",ename);
  209.          while ( (tmpc=getchar() ) != '\n' )
  210.             ;
  211.       }
  212.       else {
  213.          ename[--enamel]='\0';
  214.       }
  215.       if ( enamel <= 0 )
  216.          break;
  217.       jobl = asks("Enter employee job   : ",job,(int)joblmax+1);
  218.       if ( jobl == joblmax && job[jobl] != '\n' ) {
  219.          printf("Job title too long; truncated to \"%s\"\n",job);
  220.          while ( (tmpc=getchar() ) != '\n' )
  221.          ;
  222.       }
  223.       else {
  224.          job[--jobl]='\0';
  225.          }
  226.       askn("Enter employee salary: ",&sal);
  227.       do {
  228.          if (askn("Enter employee dept  :   ",&deptno) < 0 )
  229.         goto errexit;
  230.      if (obndrn(C1, 1, UCP(&deptno), sizeof(deptno),
  231.          INT, -1, (char *)0, -1, -1)
  232.       || oexec(C1)
  233.       || ofetch(C1))
  234.      {
  235.         printf("\nNo such department %d\n", deptno);
  236.         deptno = -1;
  237.      }
  238.       } while (deptno == -1);
  239.  
  240. /*
  241. ** EXECUTE THE STATEMENTS.  IF A DUPLICATE empno OCCURS, CALCULATE THE
  242. ** NEXT ONE AND EXECUTE AGAIN.
  243. */
  244.       while (oexec(C0) == DUPLICATE_VALUE)
  245.       {
  246.      empno += 10;
  247.       }
  248.  
  249. /*
  250. ** IF ANY ERROR FROM OEXEC OCCURS AT THIS POINT, EXIT.
  251. */
  252.       if (C0->csrrc)
  253.       {
  254.      errrpt(C0);
  255.      goto errexit;
  256.       }
  257.  
  258. /*
  259. ** COMMIT THE CHANGE TO THE DATABASE.
  260. */
  261.       if (ocom(LDA))
  262.       {
  263.      errlda(LDA, "ocom");
  264.      goto errexit;
  265.       }
  266.  
  267. /*
  268. ** GIVE THE USER SOME FEEDBACK.
  269. */
  270.       printf("\n%s added to the %s department as employee number %d\n",
  271.          ename, dept, empno);
  272.       empno += 10;
  273.    }
  274.  
  275. /*
  276. ** EITHER AN ERROR, OR USER ENTERED END-OF-FILE FOR EMPLOYEE NAME.
  277. ** CLOSE THE CURSORS AND LOG OFF FROM ORACLE.
  278. */
  279.  
  280. errexit:
  281.    oclose(C0);
  282.    oclose(C1);
  283.    ologof(LDA);
  284.    printf ("\nEnd of the C/ORACLE example program.\n");
  285.    exit(0);
  286. }
  287.  
  288. /*
  289. ** errlda AND errrpt PRINT THE ERROR CODE, OTHER INFORMATION.
  290. */
  291.  
  292. /*void*/ errrpt(cur)
  293. struct csrdef *cur;                    /* pointer to cursor */
  294. {
  295.    char  msg[80];
  296.    printf("ORACLE error: code is %d, op is %d\n",
  297.       (int)cur->csrrc, (int)cur->csrfc);
  298.    oermsg(cur->csrrc, msg);
  299.    printf("%s\n",msg);
  300. }
  301.  
  302. /* void */ errlda(lda,msg)
  303. struct    csrdef *lda;                   /* pointer to the LDA */
  304. char    msg[];                       /* user specified message */
  305. {
  306.    char    oertxt[80];
  307.    printf ("LDA error (%s): code is %d\n", msg, (int)lda->csrrc);
  308.    oermsg(lda->csrrc, oertxt);
  309.    printf("%s\n",oertxt);
  310. }
  311.  
  312. /*
  313. **
  314. ** int askn(text,variable)
  315. **
  316. **  print the 'text' on STDOUT and read an integer variable from
  317. **  SDTIN.
  318. **
  319. **  text points to the null terminated string to be printed
  320. **  variable points to an integer variable
  321. **
  322. **  askn returns a 1 if the variable was read successfully or a
  323. **      -1 if -eof- was encountered
  324. */
  325.  
  326. int askn(text,variable)
  327.    char text[];
  328.    int    *variable;
  329. {
  330.    char s[20];
  331.    int len,tmpc;
  332.  
  333.    printf(text);
  334.    if ( fgets(s,20,stdin) == (char *)0 )
  335.      return(EOF);
  336.    len=strlen(s);
  337.  
  338.    if ( len == 19 && s[len-1] != '\n' ) {
  339.       printf("Value too long; truncated to \"%s\"\n",s);
  340.       while ( (tmpc=getchar() ) != '\n' )
  341.          ;
  342.    }
  343.    else {
  344.       s[len-1]='\0';
  345.       len--;
  346.    }
  347.  
  348.    *variable = atoi(s);
  349.    return(1);
  350. }
  351.  
  352. /*
  353. ** int asks(text,variable)
  354. **
  355. **  print the 'text' on STDOUT and read up to 'len' characters into
  356. **  the buffer pointed to by variable from STDIN.
  357. **
  358. **  text points to the null terminated string to be printed
  359. **  variable points to a buffer of at least 'len'+1 characters
  360. **
  361. **   asks returns the number of character read into the string, or a
  362. **       -1 if -eof- was encountered
  363. */
  364.  
  365. int asks(text,variable,vlen)
  366.    char text[],variable[];int vlen;
  367. {
  368.    printf(text);
  369.    return( fgets(variable,vlen,stdin) == (char *)0 ? EOF : strlen(variable) );
  370. }
  371.