odbctest.c
上传用户:canger333
上传日期:2013-01-31
资源大小:454k
文件大小:9k
源码类别:

Oracle数据库

开发平台:

Unix_Linux

  1. /*
  2.  *  odbctest.c
  3.  *
  4.  *  $Id: odbctest.c,v 1.1 1996/04/18 12:01:02 source Exp $
  5.  *
  6.  *  Sample ODBC program
  7.  *
  8.  *  (C)Copyright 1996 OpenLink Software.
  9.  *  All Rights Reserved.
  10.  *
  11.  *  The copyright above and this notice must be preserved in all
  12.  *  copies of this source code.  The copyright above does not
  13.  *  evidence any actual or intended publication of this source code.
  14.  *
  15.  *  This is unpublished proprietary trade secret of OpenLink Software.
  16.  *  This source code may not be copied, disclosed, distributed, demonstrated
  17.  *  or licensed except as authorized by OpenLink Software.
  18.  */
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include "iodbc.h"
  22. #include "isql.h"
  23. #include "isqlext.h"
  24. #define MAXCOLS 32
  25. HENV henv;
  26. HDBC hdbc;
  27. HSTMT hstmt;
  28. int connected;
  29. /*
  30.  *  Connect to the datasource
  31.  *
  32.  *  The connect string can have the following parts and they refer to
  33.  *  the values in the odbc.ini file
  34.  *
  35.  * DSN=<data source name> [mandatory]
  36.  * HOST=<server host name> [optional - value of Host]
  37.  * SVT=<database server type> [optional - value of ServerType]
  38.  * DATABASE=<database path> [optional - value of Database]
  39.  * OPTIONS=<db specific opts> [optional - value of Options]
  40.  * UID=<user name> [optional - value of LastUser]
  41.  * PWD=<password> [optional]
  42.  * READONLY=<N|Y> [optional - value of ReadOnly]
  43.  * FBS=<fetch buffer size> [optional - value of FetchBufferSize]
  44.  *
  45.  *   Examples:
  46.  *
  47.  * HOST=star;SVT=Informix 5;UID=demo;PWD=demo;DATABASE=stores5
  48.  *
  49.  * DSN=stores5_informix;PWD=demo
  50.  */
  51. int
  52. DB_Connect (char *connStr)
  53. {
  54.   short buflen;
  55.   char buf[257];
  56.   int status;
  57.   if (SQLAllocEnv (&henv) != SQL_SUCCESS)
  58.     return -1;
  59.   if (SQLAllocConnect (henv, &hdbc) != SQL_SUCCESS)
  60.     return -1;
  61.   status = SQLDriverConnect (hdbc, 0, (UCHAR *) connStr, SQL_NTS, (UCHAR *) buf,
  62.        sizeof (buf), &buflen, SQL_DRIVER_COMPLETE);
  63.   if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO)
  64.     return -1;
  65.   connected = 1;
  66.   if (SQLAllocStmt (hdbc, &hstmt) != SQL_SUCCESS)
  67.     return -1;
  68.   return 0;
  69. }
  70. /*
  71.  *  Disconnect from the database
  72.  */
  73. int
  74. DB_Disconnect (void)
  75. {
  76.   if (hstmt)
  77.     SQLFreeStmt (hstmt, SQL_DROP);
  78.   if (connected)
  79.     SQLDisconnect (hdbc);
  80.   if (hdbc)
  81.     SQLFreeConnect (hdbc);
  82.   if (henv)
  83.     SQLFreeEnv (henv);
  84.   return 0;
  85. }
  86. /*
  87.  *  This is the message handler for the communications layer.
  88.  *
  89.  *  The messages received here are not passed through SQLError,
  90.  *  because they might occur when no connection is established.
  91.  *
  92.  *  Typically, Rejections from oplrqb are trapped here, and
  93.  *  also RPC errors.
  94.  *
  95.  *  When no message handler is installed, the messages are output to stderr
  96.  */
  97. void
  98. DB_MesgHandler (char *reason)
  99. {
  100.   fprintf (stderr, "DB_MesgHandler: %sn", reason);
  101. }
  102. /*
  103.  *  Show all the error information that is available
  104.  */
  105. int
  106. DB_Errors (char *where)
  107. {
  108.   unsigned char buf[250];
  109.   unsigned char sqlstate[15];
  110.   /*
  111.    *  Get statement errors
  112.    */
  113.   while (SQLError (henv, hdbc, hstmt, sqlstate, NULL,
  114.       buf, sizeof(buf), NULL) == SQL_SUCCESS)
  115.     {
  116.       fprintf (stderr, "%s, SQLSTATE=%sn", buf, sqlstate);
  117.     }
  118.   /*
  119.    *  Get connection errors
  120.    */
  121.   while (SQLError (henv, hdbc, SQL_NULL_HSTMT, sqlstate, NULL,
  122.       buf, sizeof(buf), NULL) == SQL_SUCCESS)
  123.     {
  124.       fprintf (stderr, "%s, SQLSTATE=%sn", buf, sqlstate);
  125.     }
  126.   /*
  127.    *  Get environmental errors
  128.    */
  129.   while (SQLError (henv, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlstate, NULL,
  130.       buf, sizeof(buf), NULL) == SQL_SUCCESS)
  131.     {
  132.       fprintf (stderr, "%s, SQLSTATE=%sn", buf, sqlstate);
  133.     }
  134.   return -1;
  135. }
  136. /*
  137.  *  Test program to run on the connected database
  138.  */
  139. int
  140. DB_Test ()
  141. {
  142.   char request[512];
  143.   char fetchBuffer[1000];
  144.   short displayWidths[MAXCOLS];
  145.   short displayWidth;
  146.   short numCols;
  147.   short colNum;
  148.   char colName[50];
  149.   short colType;
  150.   UDWORD colPrecision;
  151.   SDWORD colIndicator;
  152.   short colScale;
  153.   short colNullable;
  154.   UDWORD totalRows;
  155.   int i;
  156.   while (1)
  157.     {
  158.       /*
  159.        *  Ask the user for a dynamic SQL statement
  160.        */
  161.       printf ("nSQL>");
  162.       if (fgets (request, sizeof (request), stdin) == NULL)
  163.         break;
  164.       request[strlen (request) - 1] = '';
  165.       if (request[0] == '')
  166.         continue;
  167.       /*
  168.        *  If the user just types tables, give him a list
  169.        */
  170.       if (!strcmp (request, "tables"))
  171.         {
  172.    if (SQLTables (hstmt, "", SQL_NTS, "", SQL_NTS, "", SQL_NTS, 
  173.   "", SQL_NTS) != SQL_SUCCESS)
  174.      {
  175.        DB_Errors ("SQLTables");
  176.        continue;
  177.      }
  178. }
  179.       else if (!strcmp (request, "quit") || !strcmp (request, "exit"))
  180.         break; /* If you want to quit, just say so */
  181.       else
  182.         {
  183.   /*
  184.    *  Prepare & Execute the statement
  185.    */
  186.   if (SQLPrepare (hstmt, (UCHAR *) request, SQL_NTS) != SQL_SUCCESS)
  187.     {
  188.       DB_Errors ("SQLPrepare");
  189.       continue;
  190.     }
  191.   if (SQLExecute (hstmt) != SQL_SUCCESS)
  192.     {
  193.       DB_Errors ("SQLExec");
  194.       continue;
  195.     }
  196.         }
  197.       /*
  198.        *  Get the number of result columns for this cursor.
  199.        *  If it is 0, then the statement was probably a select
  200.        */
  201.       if (SQLNumResultCols (hstmt, &numCols) != SQL_SUCCESS)
  202. {
  203.   DB_Errors ("SQLNumResultCols");
  204.   goto endCursor;
  205. }
  206.       if (numCols == 0)
  207.         {
  208.   printf ("Statement executed.n");
  209.   goto endCursor;
  210. }
  211.     
  212.       if (numCols > MAXCOLS)
  213.         numCols = MAXCOLS;
  214.       /*
  215.        *  Get the names for the columns
  216.        */
  217.       for (colNum = 1; colNum <= numCols; colNum++)
  218. {
  219.   /*
  220.    *  Get the name and other type information
  221.    */
  222.   if (SQLDescribeCol (hstmt, colNum, (UCHAR *) colName,
  223.           sizeof (colName), NULL, &colType, &colPrecision,
  224.   &colScale, &colNullable) != SQL_SUCCESS)
  225.     {
  226.       DB_Errors ("SQLDescribeCol");
  227.       goto endCursor;
  228.     }
  229.   /*
  230.    *  Calculate the display width for the column
  231.    */
  232.   switch (colType)
  233.     {
  234.     case SQL_VARCHAR:
  235.     case SQL_CHAR:
  236.       displayWidth = (short) colPrecision;
  237.       break;
  238.     case SQL_BIT:
  239.       displayWidth = 1;
  240.       break;
  241.     case SQL_TINYINT:
  242.     case SQL_SMALLINT:
  243.     case SQL_INTEGER:
  244.       displayWidth = colPrecision + 1; /* sign */
  245.       break;
  246.     case SQL_DOUBLE:
  247.     case SQL_DECIMAL:
  248.     case SQL_NUMERIC:
  249.     case SQL_FLOAT:
  250.       displayWidth = colPrecision + 2;  /* sign, comma */
  251.       break;
  252.     default:
  253.       displayWidths[colNum-1] = 0; /* skip other data types */
  254.       continue;
  255.     }
  256.   if (displayWidth < strlen (colName))
  257.     displayWidth = strlen (colName);
  258.   if (displayWidth > sizeof (fetchBuffer) - 1)
  259.     displayWidth = sizeof (fetchBuffer) - 1;
  260.   displayWidths[colNum-1] = displayWidth; 
  261.   /*
  262.    *  Print header field
  263.    */
  264.   printf ("%-*.*s", displayWidth, displayWidth, colName);
  265.   if (colNum < numCols)
  266.     putchar ('|');
  267. }
  268.       putchar ('n');
  269.       /*
  270.        *  Print second line
  271.        */
  272.       for (colNum = 1; colNum <= numCols; colNum++)
  273.         {
  274.   for (i = 0; i < displayWidths[colNum-1]; i++)
  275.     putchar ('-');
  276.   if (colNum < numCols)
  277.     putchar ('+');
  278. }
  279.       putchar ('n');
  280.       /*
  281.        *  Print all the fields
  282.        */
  283.       totalRows = 0;
  284.       while (1)
  285.         {
  286.   int sts = SQLFetch (hstmt);
  287.   if (sts == SQL_NO_DATA_FOUND)
  288.     break;
  289.   if (sts != SQL_SUCCESS)
  290.     {
  291.       DB_Errors ("Fetch");
  292.       break;
  293.     }
  294.   for (colNum = 1; colNum <= numCols; colNum++)
  295.     {
  296.       /*
  297.        *  Fetch this column as character
  298.        */
  299.       if (SQLGetData (hstmt, colNum, SQL_CHAR, fetchBuffer,
  300.   sizeof (fetchBuffer), &colIndicator) != SQL_SUCCESS)
  301. {
  302.   DB_Errors ("SQLGetData");
  303.   goto endCursor;
  304. }
  305.       /*
  306.        *  Show NULL fields as ****
  307.        */
  308.       if (colIndicator == SQL_NULL_DATA)
  309.         {
  310.   for (i = 0; i < displayWidths[colNum-1]; i++)
  311.     fetchBuffer[i] = '*';
  312.   fetchBuffer[i] = '';
  313. }
  314.       printf ("%-*.*s", displayWidths[colNum-1],
  315.           displayWidths[colNum-1], fetchBuffer);
  316.       if (colNum < numCols)
  317.         putchar ('|');
  318.     }
  319.   putchar ('n');
  320.   totalRows++;
  321. }
  322.       printf (" %lu row(s) fetched.n", totalRows);
  323.     endCursor:
  324.       SQLFreeStmt (hstmt, SQL_CLOSE);
  325.     }
  326.   return 0;
  327. }
  328. int
  329. main (int argc, char **argv)
  330. {
  331.   char dataSource[120];
  332.   puts ("OpenLink ODBC Demonstration program");
  333.   puts ("This program shows an interactive SQL processorn");
  334.   /*
  335.    *  Ask for the connect string
  336.    */
  337.   printf ("Enter ODBC connect string: ");
  338.   if (fgets (dataSource, sizeof (dataSource), stdin) == NULL)
  339.     return 1;
  340.   /*
  341.    *  Remove trailing 'n'
  342.    */
  343.   dataSource[strlen (dataSource) - 1] = '';
  344.   /*
  345.    *  If we can connect to this datasource, run the test program
  346.    */
  347.   if (DB_Connect (dataSource) != 0)
  348.     {
  349.       DB_Errors ("DB_Connect");
  350.     }
  351.   else if (DB_Test () != 0)
  352.     {
  353.       DB_Errors ("DB_Test");
  354.     }
  355.   /*
  356.    *  End the connection
  357.    */
  358.   DB_Disconnect ();
  359.   puts ("nHave a nice day.");
  360.   return 0;
  361. }