home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / 32SNIPIT.PAK / SQLBIND.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  22.6 KB  |  684 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. // Sqlbind.C
  4. #include "snipit.h"
  5.  
  6. static pCHAR szTblName = "SQLBIND";
  7.  
  8. // Field Descriptor used in creating a table.
  9. static SNIPFAR FLDDesc fldDesc[] =
  10.                         {
  11.                           { // Field 1 - FRSTNAME
  12.                             1,              // Field Number
  13.                             "FRSTNAME",     // Field Name
  14.                             fldZSTRING,     // Field Type
  15.                             fldUNKNOWN,     // Field Subtype
  16.                             10,             // Field Size ( 1 or 0, except
  17.                                             //     BLOb or CHAR field )
  18.                             0,              // Decimal places ( 0 )
  19.                                             //     computed
  20.                             0,              // Offset in record ( 0 )
  21.                             0,              // Length in Bytes  ( 0 )
  22.                             0,              // For Null Bits    ( 0 )
  23.                             fldvNOCHECKS,   // Validiy checks   ( 0 )
  24.                             fldrREADWRITE   // Rights
  25.                           },
  26.                           { // Field 2 - LASTNAME
  27.                             2, "LASTNAME", fldZSTRING, fldUNKNOWN,
  28.                             12, 0, 0, 0, 0,
  29.                             fldvNOCHECKS, fldrREADWRITE
  30.                           }
  31.                        };
  32.  
  33. // Index Descriptor - describes the index associated with the table.
  34. static IDXDesc IdxDesc =
  35.                     {
  36.                         { "BaseIdx" },      // Name
  37.                         1,                  // Number
  38.                         { NULL },           // Tag name (dBASE only)
  39.                         { NULL },           // Optional format
  40.                         FALSE,              // Primary?
  41.                         TRUE,               // Unique?
  42.                         FALSE,              // Descending?
  43.                         TRUE,               // Maintained?
  44.                         FALSE,              // SubSet?
  45.                         FALSE,              // Expression index?
  46.                         NULL,               // for QBE only
  47.                         2,                  // Fields in key
  48.                         NULL,               // Length in bytes
  49.                         FALSE,              // Index out of date?
  50.                         0,                  // Key Type of Expression
  51.                         { 2, 1 },           // Array of field numbers
  52.                         { NULL },           // Key expression
  53.                         { NULL },           // Key Condition
  54.                         FALSE,              // Case insensitive
  55.                         0,                  // Block size in bytes
  56.                         0                   // Restructure number
  57.                     };
  58.  
  59. // Function prototypes
  60. static DBIResult CreateSQLTable(hDBIDb hDb, pCHAR pszTblName);
  61. static void CleanUp(pBYTE pRecBuf, pFLDDesc pfldDesc, hDBIStmt *hStmt,
  62.                     hDBIDb *hDb, hDBICur *hCur, hDBICur *hAnsCur,
  63.                     pCHAR szTblName, hDBIXact hTran, CHAR *szDbType);
  64.  
  65. static const UINT16 uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
  66.                     
  67. //=====================================================================
  68. //  Function:
  69. //          SQLBind();
  70. //
  71. //  Description:
  72. //          This example shows how to use Parameter Binding with Query's.
  73. //          Parameter binding allows you to re-execute a SQL query with
  74. //          different parameters without having to prepare the query
  75. //          (which is done by calling DbiQPrepare) over and over....
  76. //          This can result in dramatic speed improvements.
  77. //
  78. //          This sample shows two examples which search for values in a
  79. //          table:
  80. //            Example 1: The table has been opened.  The table's
  81. //               field description structure and record buffer are
  82. //               used to define the parameter values for DbiQSetParams().
  83. //               This method is useful if the parameters in the SQL
  84. //               query exactly match the field descriptions for the
  85. //               table, as is often found in Inserts and updates.
  86. //
  87. //            Example 2: The table has not been opened. The client
  88. //               builds the logical field description structure and record
  89. //               buffer used to define the parameter values for
  90. //               DbiQSetParams().
  91. //
  92. //  WARNING: This example requires write access to the SQL server.
  93. //=====================================================================
  94. void
  95. SQLBind (void)
  96. {
  97.     hDBIDb      hDb = NULL;         // Handle to the Database.
  98.     hDBICur     hCur = NULL;        // Handle to the Table.
  99.     hDBICur     hAnsCur = NULL;     // Handle to the Answer Set
  100.     DBINAME     szDbType;           // Type of the Database
  101.     DBIResult   rslt;               // Return value from IDAPI functions
  102.     UINT16      uLength;            // Length of property return from DbiGetProp
  103.     hDBIStmt    hStmt = NULL;       // Handle to the Query Statement
  104.     CURProps    curProps;           // Table Properties
  105.     pBYTE       pRecBuf = NULL;     // Record Buffer
  106.     pFLDDesc    pfldDesc = NULL,    // Field Descriptor for the Table
  107.                 pfldDescT;
  108.     UINT16      uParam, uParams;    // Number of parameters
  109.     UINT16      uRecBufSize;        // Record buffer size
  110.     hDBIXact    hTran = 0;          // Transaction handle
  111.     int         i;                  // Loop counter
  112.  
  113.     CHAR        szInsert[]     = {    // SQL statement for insert
  114.                  "INSERT INTO SQLBIND (FRSTNAME, LASTNAME) VALUES"
  115.                  "(?, ?)"
  116.                                };
  117.  
  118.     CHAR        szQry1[]     = {    // SQL statement for Example 1
  119.                  "SELECT * FROM SQLBIND "
  120.                  "WHERE FRSTNAME = ? and LASTNAME = ?"
  121.                                };
  122.  
  123.     CHAR        szQry2[]     = {    // SQL statement for Example 2
  124.                  "SELECT * FROM SQLBIND "
  125.                  "WHERE FRSTNAME = ? or FRSTNAME = ?"
  126.                                };
  127.  
  128.     Screen("*** SQL Parameter Binding Example ***\r\n");
  129.  
  130.     BREAK_IN_DEBUGGER();
  131.  
  132.     Screen("    Initializing IDAPI...");
  133.     if (InitAndConnect2(&hDb) != DBIERR_NONE)
  134.     {
  135.         Screen("\r\n*** End of Example ***");
  136.         return;
  137.     }  
  138.  
  139.     rslt = DbiGetProp(hDb, dbDATABASETYPE, szDbType, sizeof(DBINAME),
  140.                       &uLength);
  141.     ChkRslt(rslt, "GetProp");
  142.  
  143.     // Create the table
  144.  
  145.     if (CreateSQLTable(hDb, szTblName)
  146.         != DBIERR_NONE)
  147.     {
  148.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  149.                 hTran, szDbType);
  150.         return;
  151.     }
  152.  
  153.     rslt = DbiOpenTable(hDb, szTblName, NULL,
  154.                         NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
  155.                         xltFIELD, FALSE, NULL, &hCur);
  156.     if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
  157.     {
  158.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  159.                 hTran, szDbType);
  160.         return;
  161.     }
  162.  
  163.     // Set up Record buffer and Field Descriptor.
  164.     rslt = DbiGetCursorProps(hCur, &curProps);
  165.     ChkRslt(rslt, "GetCursorProps");
  166.  
  167.     uRecBufSize = (UINT16)(curProps.iRecBufSize * sizeof(BYTE));
  168.  
  169.     pRecBuf = (pBYTE) malloc(uRecBufSize);
  170.     pfldDesc = (pFLDDesc) malloc(curProps.iFields * sizeof(FLDDesc));
  171.     if ((!pfldDesc) || (!pRecBuf))
  172.     {
  173.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  174.                 hTran, szDbType);
  175.         return;
  176.     }
  177.  
  178.     rslt = DbiGetFieldDescs(hCur, pfldDesc);
  179.     ChkRslt(rslt, "GetFieldDescs");
  180.  
  181.     // Make certain field numbers are not set
  182.     for (i=0; i < curProps.iFields; i++)
  183.     {
  184.         pfldDesc[i].szName[0] = 0;
  185.     }
  186.  
  187.     uParams = curProps.iFields;
  188.  
  189.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  190.     ChkRslt(rslt, "BeginTran");
  191.  
  192.     Screen("    Allocate the statement handle...");
  193.     rslt = DbiQAlloc(hDb, qrylangSQL, &hStmt);
  194.     ChkRslt(rslt, "QAlloc");
  195.  
  196.     Screen("\r\n    Prepare the SQL insert statement...");
  197.     rslt = DbiQPrepare(hStmt, szInsert);
  198.     ChkRslt(rslt, "QPrepare");
  199.  
  200.     Screen("    Insert some records using the following SQL statement:\r\n");
  201.     Screen("        %s\r\n", szInsert);
  202.  
  203.     memset((void*)pRecBuf, 0, uRecBufSize);
  204.     memcpy((void*)(pRecBuf + pfldDesc[0].iOffset), "Tracy", 5);
  205.     memcpy((void*)(pRecBuf + pfldDesc[1].iOffset), "Smith", 5);
  206.  
  207.     rslt = DbiQSetParams(hStmt, uParams, pfldDesc, pRecBuf);
  208.     if (ChkRslt(rslt, "QSetParams") != DBIERR_NONE)
  209.     {
  210.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  211.                 hTran, szDbType);
  212.         return;
  213.     }
  214.  
  215.     rslt = DbiQExec(hStmt, NULL);
  216.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  217.     {
  218.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  219.                 hTran, szDbType);
  220.         return;
  221.     }
  222.  
  223.     memset((void*)pRecBuf, 0, uRecBufSize);
  224.     memcpy((void*)(pRecBuf + pfldDesc[0].iOffset), "David", 5);
  225.     memcpy((void*)(pRecBuf + pfldDesc[1].iOffset), "Duncan", 6);
  226.  
  227.     rslt = DbiQSetParams(hStmt, uParams, pfldDesc, pRecBuf);
  228.     if (ChkRslt(rslt, "QSetParams") != DBIERR_NONE)
  229.     {
  230.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  231.                 hTran, szDbType);
  232.         return;
  233.     }
  234.  
  235.     rslt = DbiQExec(hStmt, NULL);
  236.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  237.     {
  238.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  239.                 hTran, szDbType);
  240.         return;
  241.     }
  242.  
  243.     memset((void*)pRecBuf, 0, uRecBufSize);
  244.     memcpy((void*)(pRecBuf + pfldDesc[0].iOffset), "John", 4);
  245.     memcpy((void*)(pRecBuf + pfldDesc[1].iOffset), "Brisco", 6);
  246.  
  247.     rslt = DbiQSetParams(hStmt, uParams, pfldDesc, pRecBuf);
  248.     if (ChkRslt(rslt, "QSetParams") != DBIERR_NONE)
  249.     {
  250.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  251.                 hTran, szDbType);
  252.         return;
  253.     }
  254.  
  255.     rslt = DbiQExec(hStmt, NULL);
  256.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  257.     {
  258.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  259.                 hTran, szDbType);
  260.         return;
  261.     }
  262.  
  263.     rslt = DbiQFree(&hStmt);
  264.     ChkRslt(rslt, "QFree");
  265.  
  266.     rslt = DbiEndTran(hDb, hTran, xendCOMMIT);
  267.     ChkRslt(rslt, "EndTran");
  268.  
  269.     ///////////////////////////////////////////////////////////////////////
  270.     // EXAMPLE 1: Table is open. Use field descriptions and
  271.     //            record buffer.
  272.     //
  273.     // SELECT * FROM SQLBind WHERE FRSTNAME = ? and LASTNAME = ?
  274.  
  275.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  276.     ChkRslt(rslt, "BeginTran");
  277.  
  278.     Screen("    Perform the following SQL statement on the table:\r\n");
  279.     Screen("        %s", szQry1);
  280.  
  281.     Screen("\r\n    Allocate the statement handle...");
  282.     rslt = DbiQAlloc(hDb, qrylangSQL, &hStmt);
  283.     ChkRslt(rslt, "QAlloc");
  284.  
  285.  
  286.     Screen("    Prepare the SQL statement...");
  287.     rslt = DbiQPrepare(hStmt, szQry1);
  288.     ChkRslt(rslt, "QPrepare");
  289.  
  290.     Screen("\r\n    Search for Tracy Smith");
  291.  
  292.     memset((void *)pRecBuf, 0, uRecBufSize);
  293.     strcpy((pCHAR)(pRecBuf + pfldDesc[0].iOffset), "Tracy");
  294.     strcpy((pCHAR)(pRecBuf + pfldDesc[1].iOffset), "Smith");
  295.  
  296.     Screen("    Set the Statement Parameters...");
  297.     rslt = DbiQSetParams(hStmt, uParams, pfldDesc, pRecBuf);
  298.     if (ChkRslt(rslt, "QSetParams") != DBIERR_NONE)
  299.     {
  300.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  301.                 hTran, szDbType);
  302.         return;
  303.     }
  304.  
  305.     Screen("    Execute the SQL statement...");
  306.     rslt = DbiQExec(hStmt, &hAnsCur);
  307.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  308.     {
  309.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  310.                 hTran, szDbType);
  311.         return;
  312.     }
  313.  
  314.     // Check for a valid cursor
  315.     if (hAnsCur)
  316.     {
  317.         Screen("    Display the answer table...");
  318.         rslt = DbiSetToBegin(hAnsCur);
  319.         ChkRslt(rslt, "SetToBegin");
  320.         DisplayTable(hAnsCur, 0);
  321.  
  322.         Screen("\r\n    Close the cursor to the answer set...");
  323.         rslt = DbiCloseCursor(&hAnsCur);
  324.         ChkRslt(rslt, "CloseCursor");
  325.         hAnsCur = 0;
  326.     }
  327.     else
  328.     {
  329.         Screen("        Could not get cursor to the answer table");
  330.     }
  331.  
  332.     Screen("\r\n    Search for John Brisco");
  333.     Screen("    Note that we do not have to call DbiQPrepare...");
  334.  
  335.     memset((void*)pRecBuf, 0, uRecBufSize);
  336.     memcpy((void*)(pRecBuf + pfldDesc[0].iOffset), "John", 4);
  337.     memcpy((void*)(pRecBuf + pfldDesc[1].iOffset), "Brisco", 6);
  338.  
  339.     Screen("    Set the Statement Parameters...");
  340.     rslt = DbiQSetParams(hStmt, uParams, pfldDesc, pRecBuf);
  341.     if (ChkRslt(rslt, "QSetParams") != DBIERR_NONE)
  342.     {
  343.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  344.                 hTran, szDbType);
  345.         return;
  346.     }
  347.  
  348.     Screen("    Execute the SQL statement...");
  349.     rslt = DbiQExec(hStmt, &hAnsCur);
  350.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  351.     {
  352.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  353.                 hTran, szDbType);
  354.  
  355.         return;
  356.     }
  357.  
  358.     // Check for a valid cursor
  359.     if (hAnsCur)
  360.     {
  361.         Screen("    Display the answer table...");
  362.         rslt = DbiSetToBegin(hAnsCur);
  363.         ChkRslt(rslt, "SetToBegin");
  364.         DisplayTable(hAnsCur, 0);
  365.  
  366.         Screen("\r\n    Close the cursor to the answer set...");
  367.         rslt = DbiCloseCursor(&hAnsCur);
  368.         ChkRslt(rslt, "CloseCursor");
  369.         hAnsCur = 0;
  370.     }
  371.     else
  372.     {
  373.         Screen("        Could not get cursor to the answer table");
  374.     }
  375.     
  376.     Screen("    Release memory allocated for the Query...");
  377.     rslt = DbiQFree(&hStmt);
  378.     ChkRslt(rslt, "QryFree");
  379.  
  380.     if (pRecBuf)
  381.     {
  382.         free(pRecBuf);
  383.         pRecBuf = NULL;
  384.     }
  385.     if (pfldDesc)
  386.     {
  387.         free(pfldDesc);
  388.     }
  389.  
  390.     rslt = DbiEndTran(hDb, hTran, xendCOMMIT);
  391.     ChkRslt(rslt, "EndTran");
  392.  
  393.     Screen("    Close the %s table...", szTblName);
  394.     rslt = DbiCloseCursor(&hCur);
  395.     ChkRslt(rslt, "CloseCursor");
  396.  
  397.     ///////////////////////////////////////////////////////////
  398.     // EXAMPLE 2: Table is not open. Use client-generated
  399.     //            logical field descriptions and record buffer.
  400.     //
  401.     // SELECT * FROM SQLBind WHERE FRSTNAME = ? or FRSTNAME = ?
  402.  
  403.     rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran);
  404.     ChkRslt(rslt, "BeginTran");
  405.  
  406.     uParams = 2;
  407.  
  408.     pfldDesc = (pFLDDesc) malloc(uParams * sizeof(FLDDesc));
  409.     if (pfldDesc == NULL)
  410.     {
  411.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  412.                 hTran, szDbType);
  413.         return;
  414.     }
  415.  
  416.     memset(pfldDesc, 0, uParams * sizeof(FLDDesc));
  417.  
  418.     // Build the logical field descriptions to pass to DbiQSetParams().
  419.  
  420.     for (pfldDescT = pfldDesc, uParam = 0; uParam < uParams; uParam++, pfldDescT++)
  421.     {
  422.         // The following fields must be set correctly:
  423.         // iFldNum     - field (parameter) number.
  424.         // iFldType    - field type.
  425.         // iUnits1     - required for string fields only.
  426.         // iLen        - for logical types, sizeof (iFldType) or
  427.         //                 iUnits1 + 1 for string types.
  428.         // iOffset     - offset in the record buffer with param value.
  429.  
  430.         pfldDescT->iFldNum     = (UINT16)(uParam + 1);
  431.         pfldDescT->iFldType    = fldZSTRING;  // IDAPI logical type.
  432.         pfldDescT->iUnits1     = 10;          // Units.
  433.         pfldDescT->iLen        = 11;          // Add 1 for NULL term.
  434.         pfldDescT->iOffset     = (UINT16)(uParam
  435.                                      ? pfldDesc[uParam-1].iOffset +
  436.                                        pfldDesc[uParam-1].iLen
  437.                                      : 0);
  438.     }
  439.  
  440.     uRecBufSize = (UINT16)(pfldDesc[uParams-1].iOffset +
  441.                            pfldDesc[uParams-1].iLen);
  442.  
  443.     pRecBuf = (pBYTE) malloc(uRecBufSize * sizeof(BYTE));
  444.     if (!pRecBuf)
  445.     {
  446.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  447.                 hTran, szDbType);
  448.         return;
  449.     }
  450.  
  451.     memset(pRecBuf, 0, uRecBufSize);
  452.  
  453.     Screen("\r\n    Allocate the statement handle...");
  454.     rslt = DbiQAlloc(hDb, qrylangSQL, &hStmt);
  455.     ChkRslt(rslt, "QAlloc");
  456.  
  457.     Screen("    Prepare the SQL statement...");
  458.     rslt = DbiQPrepare(hStmt, szQry2);
  459.     ChkRslt(rslt, "QPrepare");
  460.  
  461.     Screen("    Perform the following SQL statement on the table:\r\n");
  462.     Screen("        %s", szQry2);
  463.  
  464.     Screen("\r\n    Search for Tracy or David ");
  465.  
  466.     // Place parameter values in IDAPI logical format into the record buffer
  467.  
  468.     Screen("    Set the Statement Parameters...");
  469.     strcpy((pCHAR)(pRecBuf + pfldDesc[0].iOffset), "Tracy");
  470.     strcpy((pCHAR)(pRecBuf + pfldDesc[1].iOffset), "David");
  471.  
  472.     rslt = DbiQSetParams(hStmt, uParams, pfldDesc, pRecBuf);
  473.     if (ChkRslt(rslt, "QSetParams") != DBIERR_NONE)
  474.     {
  475.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  476.                 hTran, szDbType);
  477.         return;
  478.     }
  479.  
  480.     Screen("    Execute the SQL statement...");
  481.     rslt = DbiQExec(hStmt, &hAnsCur);
  482.     if (ChkRslt(rslt, "QExec") != DBIERR_NONE)
  483.     {
  484.         CleanUp(pRecBuf, pfldDesc, &hStmt, &hDb, &hCur, &hAnsCur, szTblName,
  485.                 hTran, szDbType);
  486.         return;
  487.     }
  488.  
  489.     // Check for a valid cursor
  490.     if (hAnsCur)
  491.     {
  492.         Screen("    Display the answer table...");
  493.         rslt = DbiSetToBegin(hAnsCur);
  494.         ChkRslt(rslt, "SetToBegin");
  495.         DisplayTable(hAnsCur, 0);
  496.  
  497.         Screen("\r\n    Close the cursor to the answer set...");
  498.         rslt = DbiCloseCursor(&hAnsCur);
  499.         ChkRslt(rslt, "CloseCursor");
  500.         hAnsCur = 0;
  501.     }
  502.     else
  503.     {
  504.         Screen("        Could not get cursor to the answer table");
  505.     }
  506.  
  507.     Screen("    Release memory allocated for the Query...");
  508.     rslt = DbiQFree(&hStmt);
  509.     ChkRslt(rslt, "QryFree");
  510.  
  511.     rslt = DbiEndTran(hDb, hTran, xendCOMMIT);
  512.     ChkRslt(rslt, "EndTran");
  513.  
  514.     // Cleanup
  515.     Screen("    Delete the table...");
  516.     if (!strcmp(szDbType, "STANDARD"))
  517.     {
  518.         rslt = DbiDeleteTable(hDb, szTblName, szPARADOX);
  519.     }
  520.     else
  521.     {
  522.         rslt = DbiDeleteTable(hDb, szTblName, NULL);
  523.     }
  524.     ChkRslt(rslt, "DeleteTable");
  525.  
  526.     Screen("    Close the Database and exit IDAPI...");
  527.     CloseDbAndExit(&hDb);
  528.  
  529.     if (pRecBuf)
  530.     {
  531.         free(pRecBuf);
  532.     }
  533.  
  534.     if (pfldDesc)
  535.     {
  536.         free(pfldDesc);
  537.     }
  538.  
  539.     Screen("\r\n*** End of Example ***");
  540. }
  541.  
  542. //=====================================================================
  543. //  Function:
  544. //          CreateSQLTable(hDb, pszTblName, phCur);
  545. //
  546. //  Input:  phDb        - Pointer to the database handle.
  547. //          pszTblName  - The name of the table to create.
  548. //          phCur       - Handle to the table
  549. //
  550. //  Return: Result returned by IDAPI.
  551. //
  552. //  Description:
  553. //          This function will create a table and add records to that
  554. //          table.
  555. //=====================================================================
  556. DBIResult
  557. CreateSQLTable (hDBIDb hDb, pCHAR pszTblName)
  558. {
  559.     DBIResult   rslt;          // Value returned from IDAPI functions
  560.     CRTblDesc   crTblDesc;     // Table Descriptor
  561.     DBINAME     szDbType;      // Type of the table
  562.     UINT16      uLength;       // Length of the string
  563.  
  564.     rslt = DbiGetProp(hDb, dbDATABASETYPE, szDbType, sizeof(DBINAME),
  565.                       &uLength);
  566.     ChkRslt(rslt, "GetProp");
  567.  
  568.     // Initialize the Table Create Descriptor.
  569.     memset(&crTblDesc, 0, sizeof(CRTblDesc));
  570.  
  571.     strcpy(crTblDesc.szTblName, pszTblName);
  572.     crTblDesc.iFldCount     = uNumFields;
  573.     crTblDesc.pfldDesc      = fldDesc;
  574.     crTblDesc.iIdxCount     = 1;
  575.     crTblDesc.pidxDesc      = &IdxDesc;
  576.  
  577.     // If standard database
  578.     if (!strcmp(szDbType, "STANDARD"))
  579.     {
  580.         rslt = DbiGetProp(hDb, dbDEFAULTDRIVER, szDbType, sizeof(DBINAME),
  581.                           &uLength);
  582.         ChkRslt(rslt, "GetProp");
  583.  
  584.         // If no default driver is set
  585.         if (!strcmp(szDbType, ""))
  586.         {
  587.             strcpy(szDbType, szPARADOX);
  588.         }
  589.  
  590.         // Set the Table Type.
  591.         strcpy(crTblDesc.szTblType, szDbType);
  592.         // No Indexes
  593.         crTblDesc.iIdxCount     = 0;
  594.         crTblDesc.pidxDesc      = NULL;
  595.     }
  596.  
  597.     Screen("    Creating the table...");
  598.     rslt = DbiCreateTable(hDb, TRUE, &crTblDesc);
  599.     if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
  600.     {
  601.         return rslt;
  602.     }
  603.  
  604.     return rslt;
  605. }
  606.  
  607. //=====================================================================
  608. //  Function:
  609. //          CleanUp(pRecBuf, pfldDesc, hStmt, hDb, hCur, szTblName, hTran,
  610. //                  szDbName)
  611. //
  612. //  Input:  pRecBuf     - Handle to the Record Buffer
  613. //          pfldDesc    - Field Descriptor
  614. //          hStmt       - Statement object
  615. //          hDb         - Handle to the Database
  616. //          hCur        - The table handle
  617. //          szTblName   - Name of the Table
  618. //          hTran       - Transaction Handle
  619. //          szDbName    - Database Type
  620. //
  621. //  Return: None
  622. //
  623. //  Description:
  624. //          This function is used to free all resources allocated
  625. //          within this example.
  626. //=====================================================================
  627. void CleanUp(pBYTE pRecBuf, pFLDDesc pfldDesc, hDBIStmt *hStmt,
  628.              hDBIDb *hDb, hDBICur *hCur, hDBICur *hAnsCur, pCHAR szTblName,
  629.              hDBIXact hTran, CHAR *szDbType)
  630.  
  631. {
  632.     DBIResult   rslt;           // Return value from IDAPI
  633.     
  634.     if (*hStmt)
  635.     {
  636.         rslt = DbiQFree(hStmt);
  637.         ChkRslt(rslt, "QryFree");
  638.     }
  639.  
  640.     if (*hCur)
  641.     {
  642.         rslt = DbiCloseCursor(hCur);
  643.         ChkRslt(rslt, "CloseCursor");
  644.     }
  645.  
  646.     if (*hAnsCur)
  647.     {
  648.         rslt = DbiCloseCursor(hAnsCur);
  649.         ChkRslt(rslt, "CloseCursor");
  650.     }
  651.  
  652.     if (hTran)
  653.     {
  654.        rslt = DbiEndTran(*hDb, hTran, xendABORT);
  655.        ChkRslt(rslt, "EndTran");
  656.     }
  657.  
  658.     if (*hDb)
  659.     {
  660.         if (!strcmp(szDbType, "STANDARD"))
  661.         {
  662.             rslt = DbiDeleteTable(*hDb, szTblName, szPARADOX);
  663.         }
  664.         else
  665.         {
  666.             rslt = DbiDeleteTable(*hDb, szTblName, NULL);
  667.         }
  668.         ChkRslt(rslt, "DeleteTable");
  669.         CloseDbAndExit(hDb);
  670.     }
  671.  
  672.     if (pRecBuf)
  673.     {
  674.         free(pRecBuf);
  675.      }
  676.  
  677.     if (pfldDesc)
  678.     {
  679.         free(pfldDesc);
  680.      }
  681.  
  682.     Screen("\r\n*** End of Example ***");
  683. }
  684.