example2.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:7k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /* -*- C -*- */
  2. /* The first example illustrates creating a table, adding some data
  3.  * to it, and selecting the inserted data. The second example shows
  4.  * interactive ad hoc query processing.
  5.  *
  6.  * Actual applications include more complete error checking following
  7.  * calls to SQL/CLI routines. That material is omitted from this
  8.  * Appendix for the sake of clarity.
  9.  *
  10.  * This file is adapted for PostgreSQL
  11.  * from the CLI Annex in the SQL98 August 1994 draft standard.
  12.  * Thomas G. Lockhart 1999-06-16
  13.  */
  14. /*
  15.  * B.2  Interactive Query
  16.  *
  17.  * This sample function uses the concise CLI functions to
  18.  * interactively execute a SQL statement supplied as an argument.
  19.  * In the case where the user types a SELECT statement, the function
  20.  * fetches and displays all rows of the result set.
  21.  *
  22.  * This example illustrates the use of GetDiagField() to identify
  23.  * the type of SQL statement executed and, for SQL statements where
  24.  * the row count is defined on all implementations, the use of
  25.  * GetDiagField() to obtain the row count.
  26.  */
  27. /*
  28.  * Sample program - uses concise CLI functions to execute
  29.  * interactively an ad hoc statement.
  30.  */
  31. #include <sqlcli.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #define  MAXCOLS   100
  35. #define  max(a,b) (a>b?a:b)
  36. int print_err(SQLSMALLINT handletype, SQLINTEGER handle);
  37. int build_indicator_message(SQLCHAR *errmsg,
  38.     SQLPOINTER *data,
  39.     SQLINTEGER collen,
  40.     SQLINTEGER *outlen,
  41.     SQLSMALLINT colnum);
  42. SQLINTEGER display_length(SQLSMALLINT coltype,
  43.   SQLINTEGER collen,
  44.   SQLCHAR *colname);
  45. example2(SQLCHAR *server, SQLCHAR *uid, SQLCHAR *authen, SQLCHAR *sqlstr)
  46. {
  47.   int         i;
  48.   SQLHENV     henv;
  49.   SQLHDBC     hdbc;
  50.   SQLHSTMT    hstmt;
  51.   SQLCHAR     errmsg[256];
  52.   SQLCHAR     colname[32];
  53.   SQLSMALLINT coltype;
  54.   SQLSMALLINT colnamelen;
  55.   SQLSMALLINT nullable;
  56.   SQLINTEGER  collen[MAXCOLS];
  57.   SQLSMALLINT scale;
  58.   SQLINTEGER  outlen[MAXCOLS];
  59.   SQLCHAR    *data[MAXCOLS];
  60.   SQLSMALLINT nresultcols;
  61.   SQLINTEGER  rowcount;
  62.   SQLINTEGER  stmttype;
  63.   SQLRETURN   rc;
  64.   /* allocate an environment handle */
  65.   SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
  66.   /* allocate a connection handle */
  67.   SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  68.   /* connect to database */
  69.   if (SQLConnect(hdbc, server, SQL_NTS, uid, SQL_NTS, authen, SQL_NTS)
  70.       != SQL_SUCCESS )
  71.     return(print_err(SQL_HANDLE_DBC, hdbc));
  72.   /* allocate a statement handle */
  73.   SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
  74.   /* execute the SQL statement */
  75.   if (SQLExecDirect(hstmt, sqlstr, SQL_NTS) != SQL_SUCCESS)
  76.     return(print_err(SQL_HANDLE_STMT, hstmt));
  77.   /* see what kind of statement it was */
  78.   SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
  79.   SQL_DIAG_DYNAMIC_FUNCTION_CODE,
  80.   (SQLPOINTER)&stmttype, 0, (SQLSMALLINT *)NULL);
  81.   switch (stmttype) {
  82.     /* SELECT statement */
  83.   case SQL_SELECT_CURSOR:
  84.     /* determine number of result columns */
  85.     SQLNumResultCols(hstmt, &nresultcols);
  86.     /* display column names */
  87.     for (i=0; i<nresultcols; i++) {
  88.       SQLDescribeCol(hstmt, i+1, colname, sizeof(colname),
  89.      &colnamelen, &coltype, &collen[i], &scale, &nullable);
  90.       /* assume there is a display_length function which
  91.  computes correct length given the data type  */
  92.       collen[i] = display_length(coltype, collen[i], colname);
  93.       (void)printf("%*.*s", collen[i], collen[i], colname);
  94.       /* allocate memory to bind column */
  95.       data[i] = (SQLCHAR *) malloc(collen[i]);
  96.       /* bind columns to program vars, converting all types to CHAR */
  97.       SQLBindCol(hstmt, i+1, SQL_CHAR, data[i], collen[i],
  98.  &outlen[i]);
  99.     }
  100.     /* display result rows */
  101.     while ((rc=SQLFetch(hstmt))!=SQL_ERROR) {
  102.       errmsg[0] = '';
  103.       if (rc ==  SQL_SUCCESS_WITH_INFO) {
  104. for (i=0; i<nresultcols; i++) {
  105.   if (outlen[i] ==  SQL_NULL_DATA || outlen[i] >= collen[i])
  106.     build_indicator_message(errmsg,
  107.                                     (SQLPOINTER *)&data[i], collen[i],
  108.                                     &outlen[i], i);
  109.   (void)printf("%*.*s ", outlen[i], outlen[i],
  110.        data[i]);
  111. } /* for all columns in this row  */
  112. /* print any truncation messages */
  113. (void)printf("n%s", errmsg);
  114.       }
  115.     } /* while rows to fetch */
  116.     SQLClose(hstmt);
  117.     break;
  118.     /* searched DELETE, INSERT or searched UPDATE statement */
  119.   case SQL_DELETE_WHERE:
  120.   case SQL_INSERT:
  121.   case SQL_UPDATE_WHERE:
  122.     /* check rowcount */
  123.     SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
  124.     SQL_DIAG_ROW_COUNT, (SQLPOINTER)&rowcount, 0,
  125.     (SQLSMALLINT *)NULL);
  126.     if (SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT)
  127. ==  SQL_SUCCESS) {
  128.       (void) printf("Operation successfuln");
  129.     }
  130.     else {
  131.       (void) printf("Operation failedn");
  132.     }
  133.     (void)printf("%ld rows affectedn", rowcount);
  134.     break;
  135.     /* other statements */
  136.   case SQL_ALTER_TABLE:
  137.   case SQL_CREATE_TABLE:
  138.   case SQL_CREATE_VIEW:
  139.   case SQL_DROP_TABLE:
  140.   case SQL_DROP_VIEW:
  141.   case SQL_DYNAMIC_DELETE_CURSOR:
  142.   case SQL_DYNAMIC_UPDATE_CURSOR:
  143.   case SQL_GRANT:
  144.   case SQL_REVOKE:
  145.     if (SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT)
  146. ==  SQL_SUCCESS) {
  147.       (void) printf("Operation successfuln");
  148.     }
  149.     else {
  150.       (void) printf("Operation failedn");
  151.     }
  152.     break;
  153.   /* implementation-defined statement */
  154.   default:
  155.     (void)printf("Statement type=%ldn", stmttype);
  156.     break;
  157.   }
  158.   /* free data buffers */
  159.   for (i=0; i<nresultcols; i++)  {
  160.     (void)free(data[i]);
  161.   }
  162.   /* free statement handle */
  163.   SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
  164.   /* disconnect from database */
  165.   SQLDisconnect(hdbc);
  166.   /* free connection handle */
  167.   SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  168.   /* free environment handle */
  169.   SQLFreeHandle(SQL_HANDLE_ENV, henv);
  170.   return(0);
  171. }
  172. /***********************************************************
  173.  The following functions are given for completeness, but are
  174.  not relevant for understanding the database processing
  175.  nature of CLI
  176. ***********************************************************/
  177. #define MAX_NUM_PRECISION 15
  178. /*#define max length of char string representation of no. as:
  179.   = max(precision) + leading sign + E + exp sign + max exp length
  180.   =  15            + 1            + 1 + 1        + 2
  181.   =  15 + 5
  182. */
  183. #define MAX_NUM_STRING_SIZE (MAX_NUM_PRECISION + 5)
  184. SQLINTEGER  display_length(SQLSMALLINT coltype, SQLINTEGER collen,
  185.    SQLCHAR *colname)
  186. {
  187.   switch (coltype) {
  188.   case SQL_VARCHAR:
  189.   case SQL_CHAR:
  190.     return(max(collen,strlen((char *)colname)));
  191.     break;
  192.   case SQL_FLOAT:
  193.   case SQL_DOUBLE:
  194.   case SQL_NUMERIC:
  195.   case SQL_REAL:
  196.   case SQL_DECIMAL:
  197.     return(max(MAX_NUM_STRING_SIZE,strlen((char *)colname)));
  198.     break;
  199.   case SQL_DATETIME:
  200.     return(max(SQL_TIMESTAMP_LEN,strlen((char *)colname)));
  201.     break;
  202.   case SQL_INTEGER:
  203.     return(max(10,strlen((char *)colname)));
  204.     break;
  205.   case SQL_SMALLINT:
  206.     return(max(5,strlen((char *)colname)));
  207.     break;
  208.   default:
  209.     (void)printf("Unknown datatype, %dn", coltype);
  210.     return(0);
  211.     break;
  212.   }
  213. }
  214. int build_indicator_message(SQLCHAR *errmsg, SQLPOINTER *data,
  215.     SQLINTEGER collen, SQLINTEGER *outlen, SQLSMALLINT colnum)
  216. {
  217.   if (*outlen ==  SQL_NULL_DATA) {
  218.     (void)strcpy((char *)data, "NULL");
  219.     *outlen=4;
  220.   }
  221.   else {
  222.     sprintf((char *)errmsg+strlen((char *)errmsg),
  223.     "%d chars truncated, col %dn", *outlen-collen+1,
  224.     colnum);
  225.     *outlen=255;
  226.   }
  227. }