Advertisement
Guest User

Untitled

a guest
Oct 12th, 2016
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.39 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <oci.h>
  4. #include <string.h>
  5.  
  6.  
  7. void check_oci_env_err(OCIEnv *env, sword retCode);
  8. void check_oci_err(OCIError *err, sword retCode);
  9.  
  10. int main(int nargs, char *args[])
  11. {
  12.     OCIEnv    *env;
  13.     OCIError  *err;
  14.     OCISvcCtx *svc;
  15.     OraText   *username = (OraText *) "enterprisedb";
  16.     OraText   *password = (OraText *) "edbpassword";
  17.     OraText   *dbname   = (OraText *) "//127.0.0.1:5432/edb";
  18.     OCIStmt   *stmt;
  19.     OCIDefine *def;
  20.     char      *value;
  21.     char       dummy;
  22.     sb2        ind = 0, rlen = 0, rcode = 0;
  23.     char      *query = "SELECT table_name FROM all_tables";
  24.  
  25.     OCIEnvInit(&env, OCI_DEFAULT, 0, NULL);
  26.     OCIHandleAlloc(env, (void *)&err, OCI_HTYPE_ERROR, 0, NULL);
  27.  
  28.     check_oci_err(err, OCILogon2(env, err, &svc, username, strlen(username), password, strlen(password), dbname, strlen(dbname), OCI_DEFAULT));
  29.  
  30.     OCIHandleAlloc(env, (void *)&stmt, OCI_HTYPE_STMT, 0, NULL);
  31.  
  32.     check_oci_err(err, OCIStmtPrepare(stmt, err, query, strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT));
  33.  
  34.     /*
  35.      * This query fetches a single column. We don't know how big each value in the result set
  36.      * will be until we actually fetch the value.
  37.      *
  38.      * So we execute the statement and specify iters=0 to tell the OCI that it should *not* fetch
  39.      * any row as part of the OCIStmtExecute() call.
  40.      */
  41.  
  42.     check_oci_err(err, OCIStmtExecute(svc, stmt, err, /* iters */0, 0, NULL, NULL, OCI_STMT_SCROLLABLE_READONLY));
  43.  
  44.     /*
  45.      * Now we can fetch rows from the result set
  46.      */
  47.     for( ; ; )
  48.     {
  49.         /*
  50.          * Since we don't know how large this next value will be, we define the output
  51.          * buffer as a single byte (dummy)...
  52.          */
  53.         value = &dummy;
  54.         check_oci_err(err, OCIDefineByPos(stmt, &def, err, 1, value, sizeof(dummy), SQLT_CHR, &ind, &rlen, &rcode, OCI_DEFAULT));
  55.  
  56.         /*
  57.          * and, when we fetch, we expect to get warning that a value was truncated... OCIStmtFetch2() will
  58.          * return OCI_SUCCESS_WITH_INFO (note: OCIStmtFetch2() will actually return part of the column - since
  59.          * we defined a one-byte output buffer, OCIStmtFetch2() will write the first byte of the value into
  60.          * the output buffer (dummy).  If you wish, you could bind to a buffer large enough to hold *most* values
  61.          * and then re-define and re-fetch if you encounter a value too large to fit into that space.
  62.          */
  63.         sword result = OCIStmtFetch2(stmt, err, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT);
  64.  
  65.         /*
  66.          * If we got an OCI_SUCCESS_WITH_INFO, we assume that OCIStmtFetch2() truncated one or more of the
  67.          * values that we fetched.  For each column, OCIStmtFetch2() returns the *actual* length of the value
  68.          * in the indicator variable (see the earlier call to OCIDefineByPos()).
  69.          */
  70.         printf("result(%d) ind(%d) rlen(%d) rcode(%d)\n", result, ind, rlen, rcode);
  71.  
  72.         if (result == OCI_SUCCESS_WITH_INFO)
  73.         {
  74.             /*
  75.              * OCIStmtFetch2() returned a result that indicates that a value has been truncated (we should probably
  76.              * check for the exact error code here, just to make sure).
  77.              *
  78.              * Now that we know how much space we need, we can malloc() a buffer large enough to hold the value (we
  79.              * add one byte to hold the null terminator).
  80.              *
  81.              * Then we call OCIDefineByPos() to give the OCI the address of this new buffer, and we re-fetch the
  82.              * same row out of the result set by cal OCIStmtFetch2() again with orientation=OCI_FETCH_CURRENT.
  83.              */
  84.             value = malloc(ind+1);
  85.             check_oci_err(err, OCIDefineByPos(stmt, &def, err, 1, value, ind+1, SQLT_CHR, &ind, &rlen, &rcode, OCI_DEFAULT));
  86.             check_oci_err(err, OCIStmtFetch2(stmt, err, 1, OCI_FETCH_CURRENT, 0, OCI_DEFAULT));
  87.        
  88.             printf("refetched - %*.*s\n", rlen, rlen, value);
  89.             printf("ind(%d) rlen(%d) rcode(%d)\n", ind, rlen, rcode);
  90.         }
  91.         else if (result == OCI_NO_DATA)
  92.         {
  93.             break;
  94.         }
  95.     }
  96.  
  97.     check_oci_err(err, OCILogoff(svc, err));
  98.  
  99.     OCIHandleFree(err, OCI_HTYPE_ERROR);
  100.     OCIHandleFree(env, OCI_HTYPE_ENV);
  101.  
  102.     return 0;
  103. }
  104.  
  105. /******************************************************************************
  106.  *
  107.  *                          Environment Error Handling
  108.  *
  109.  ******************************************************************************/
  110. void check_oci_env_err(OCIEnv *env, sword retCode)
  111. {
  112.     char    szBuf[512];
  113.     sb4     errCode;
  114.  
  115.  
  116.     switch(retCode)
  117.     {
  118.         case OCI_SUCCESS:
  119.             break;
  120.  
  121.         case OCI_SUCCESS_WITH_INFO:
  122.             {
  123.                 memset(szBuf, 0, 512);
  124.                 OCIErrorGet(env, 1, NULL, &errCode, szBuf, 512, OCI_HTYPE_ENV);
  125.                 printf("OCI_SUCCESS_WITH_INFO : %s\n", szBuf);
  126.             }
  127.             break;
  128.  
  129.         case OCI_RESERVED_FOR_INT_USE:
  130.             break;
  131.  
  132.         case OCI_NO_DATA:
  133.             printf("OCI_NO_DATA\n", szBuf);
  134.             break;
  135.  
  136.         case OCI_ERROR:
  137.             {
  138.                 memset(szBuf, 0, 512);
  139.                 OCIErrorGet(env, 1, NULL, &errCode, szBuf, 512, OCI_HTYPE_ENV);
  140.                 printf("OCI_ERROR : %s\n", szBuf);
  141.             }
  142.             break;
  143.  
  144.         case OCI_INVALID_HANDLE:
  145.             break;
  146.  
  147.         case OCI_NEED_DATA:
  148.             break;
  149.  
  150.         case OCI_STILL_EXECUTING:
  151.             break;
  152.     }
  153. }
  154.  
  155. /******************************************************************************
  156.  *
  157.  *                              Error Handling
  158.  *
  159.  ******************************************************************************/
  160. void check_oci_err(OCIError *err, sword retCode)
  161. {
  162.     char    szBuf[512];
  163.     sb4     errCode;
  164.     sword   status;
  165.     ub4     recordno;
  166.  
  167.  
  168.     switch(retCode)
  169.     {
  170.         case OCI_SUCCESS:
  171.             break;
  172.  
  173.         case OCI_SUCCESS_WITH_INFO:
  174.             {
  175.                 recordno = 1;
  176.  
  177.                 memset(szBuf, 0, 512);
  178.                 status = OCIErrorGet(err, recordno++, NULL, &errCode, szBuf, 512, OCI_HTYPE_ERROR);
  179.                 while(status != OCI_NO_DATA)
  180.                 {
  181.                     printf("OCI_ERROR : %s\n", szBuf);
  182.  
  183.                     memset(szBuf, 0, 512);
  184.                     status = OCIErrorGet(err, recordno++, NULL, &errCode, szBuf, 512, OCI_HTYPE_ERROR);
  185.                 }
  186.             }
  187.             break;
  188.  
  189.         case OCI_RESERVED_FOR_INT_USE:
  190.             break;
  191.  
  192.         case OCI_NO_DATA:
  193.             printf("OCI_NO_DATA\n", szBuf);
  194.             break;
  195.  
  196.         case OCI_ERROR:
  197.             {
  198.                 recordno = 1;
  199.  
  200.                 memset(szBuf, 0, 512);
  201.                 status = OCIErrorGet(err, recordno++, NULL, &errCode, szBuf, 512, OCI_HTYPE_ERROR);
  202.                 while(status != OCI_NO_DATA)
  203.                 {
  204.                     printf("OCI_ERROR : %s\n", szBuf);
  205.  
  206.                     memset(szBuf, 0, 512);
  207.                     status = OCIErrorGet(err, recordno++, NULL, &errCode, szBuf, 512, OCI_HTYPE_ERROR);
  208.                 }
  209.             }
  210.             break;
  211.  
  212.         case OCI_INVALID_HANDLE:
  213.             break;
  214.  
  215.         case OCI_NEED_DATA:
  216.             break;
  217.  
  218.         case OCI_STILL_EXECUTING:
  219.             break;
  220.     }
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement