home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / DBSQL.ZIP / DBSQL.SQC < prev    next >
Text File  |  1990-12-02  |  19KB  |  721 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /* MODULE     : DBSQL.SQC                                                   */
  4. /* TITLE      : SQL API for C                                               */
  5. /* ENVIROMENT : OS/2 Base Enviroment                                        */
  6. /* VERSION    : 1.10                                                        */
  7. /* STATUS     : ALPHA                                                       */
  8. /*                                                                          */
  9. /* DEVELOPED BY:                                                            */
  10. /*      Bradley S. Gibson                                                   */
  11. /*                                                                          */
  12. /* COPYRIGHT:                                                               */
  13. /*      Copyright (c) 1989, 1990 Bradley S. Gibson                          */
  14. /*                                                                          */
  15. /*  DESCRIPTION:                                                            */
  16. /*                                                                          */
  17. /* MODULE REQUIREMENTS:                                                     */
  18. /*                                                                          */
  19. /****************************************************************************/
  20.  
  21. #include <os2.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdarg.h>
  26. #include <math.h>
  27.  
  28. #include <sqlenv.h>        // SQL OS/2 EE 1.2
  29. #include <sqlcodes.h>
  30. #include <sql.h>
  31. #include <sqlca.h>
  32. #include <sqlda.h>
  33. #include <sqlutil.h>
  34.  
  35. #include "\muglib\upm.h"        // User Profile Management
  36.  
  37. #include "dbsql.h"
  38.  
  39. EXEC SQL INCLUDE SQLCA;
  40.  
  41. EXEC SQL BEGIN DECLARE SECTION;
  42.  
  43.     char    *pszSqlCommandBuffer;
  44.  
  45. EXEC SQL END DECLARE SECTION;
  46.  
  47. EXEC SQL WHENEVER SQLWARNING continue;
  48.  
  49. #define NOTFOUND    100
  50.  
  51. SHORT sSqlProcessNumber = 0;
  52.  
  53.  
  54. BOOL CEXPENTRY SqlCreateDatabase ( PSZ pszDbName, PSZ pszComment,  CHAR cDrive )
  55. {
  56.     sqlecred ( pszDbName, cDrive, pszComment, 0, &sqlca );
  57.  
  58.     if ( sqlca.sqlcode == 0 )
  59.         return TRUE;
  60.     
  61.     return FALSE;
  62. }
  63.  
  64.  
  65. /****************************************************************************/
  66. /*
  67.     FUNCTION:    SqlOpenDB ( )
  68.     
  69.     DESCRIPTION: 
  70.     
  71.     PARAMETERS:  
  72.  
  73.     RETURNS:     
  74. */
  75. /****************************************************************************/
  76.  
  77. PSQLPROCESS CEXPENTRY SqlOpenDB ( PSZ pszDbName )
  78. {
  79.     PSQLPROCESS pSqlProcess;
  80.  
  81.     pSqlProcess = (PSQLPROCESS) malloc ( sizeof (SQLPROCESS) );
  82.     pSqlProcess->pszCmdBuf =  (CHAR *) malloc ( SQL_MAXCMDBUF );
  83.  
  84.     strcpy ( pSqlProcess->szDbName,   pszDbName );
  85.     strcpy ( pSqlProcess->pszCmdBuf, "" );
  86.     pSqlProcess->sProcessNum = sSqlProcessNumber;
  87.     sSqlProcessNumber++;
  88.     
  89.     // START DATABASE MANAGER
  90.     sqlestar ( );
  91.     
  92.     // DYNAMIC BIND TO DATABASE
  93.     sqlabind ( "dbsql.bnd", pSqlProcess->szDbName, NULL, NULL, NULL, &sqlca );
  94.     
  95.     // START USING DATABASE
  96.     sqlestrd ( pSqlProcess->szDbName, 'S', &sqlca );
  97.  
  98.     return pSqlProcess;
  99. }
  100.  
  101.  
  102.  
  103. /****************************************************************************/
  104. /*
  105.     FUNCTION:    SqlCloseDB ( )
  106.     
  107.     DESCRIPTION: 
  108.     
  109.     PARAMETERS:  
  110.  
  111.     RETURNS:     
  112. */
  113. /****************************************************************************/
  114.  
  115. VOID CEXPENTRY SqlCloseDB    ( PSQLPROCESS pSqlProcess )
  116. {
  117.     SqlCommit ( pSqlProcess );
  118.     
  119.     // STOP USING DATABASE
  120.     sqlestpd ( &sqlca );
  121.     
  122.     free ( pSqlProcess->pszCmdBuf );
  123.     free ( pSqlProcess->pBindVar );
  124.     free ( pSqlProcess );
  125. }
  126.  
  127.  
  128.  
  129. /****************************************************************************/
  130. /*
  131.     FUNCTION:    SqlCommand ( )
  132.     
  133.     DESCRIPTION: 
  134.     
  135.     PARAMETERS:  
  136.  
  137.     RETURNS:     
  138. */
  139. /****************************************************************************/
  140.  
  141. BOOL CEXPENTRY SqlCommand ( PSQLPROCESS pSqlProcess, PSZ pszSqlCmd )
  142. {
  143.     strcat ( pSqlProcess->pszCmdBuf, pszSqlCmd );
  144.     
  145.     return TRUE;
  146. }
  147.  
  148.  
  149.  
  150. /****************************************************************************/
  151. /*
  152.     FUNCTION:    SqlCommandf ( )
  153.     
  154.     DESCRIPTION: 
  155.     
  156.     PARAMETERS:  
  157.  
  158.     RETURNS:     
  159. */
  160. /****************************************************************************/
  161.  
  162. BOOL CEXPENTRY SqlCommandf ( PSQLPROCESS pSqlProcess, PSZ pszSqlCmd, ... )
  163. {   
  164.     CHAR szTmpBuf [512];
  165.     va_list arg_ptr;
  166.     
  167.     va_start ( arg_ptr, pszSqlCmd );
  168.     vsprintf ( szTmpBuf, pszSqlCmd, arg_ptr );
  169.     va_end   ( arg_ptr );
  170.     
  171.     SqlCommand ( pSqlProcess, szTmpBuf );
  172.     
  173.     return TRUE;
  174. }
  175.  
  176.  
  177.  
  178. /****************************************************************************/
  179. /*
  180.     FUNCTION:    SqlExecute ( )
  181.     
  182.     DESCRIPTION: 
  183.     
  184.     PARAMETERS:  
  185.  
  186.     RETURNS:     
  187. */
  188. /****************************************************************************/
  189.  
  190. BOOL CEXPENTRY SqlExecute ( PSQLPROCESS pSqlProcess )
  191. {   
  192.     PSQLDA pSqlDa;
  193.  
  194.     pSqlDa = AllocSqlDa ( 1 );
  195.  
  196.     pszSqlCommandBuffer = pSqlProcess->pszCmdBuf;
  197.  
  198.     EXEC SQL
  199.     PREPARE stmt INTO :*pSqlDa FROM :pszSqlCommandBuffer;
  200.  
  201.     if ( pSqlDa->sqld == 0 )      // Non Select Statement
  202.     {
  203.         EXEC SQL EXECUTE stmt;
  204.     }
  205.     else                          // Select Statement
  206.     {
  207.         pSqlDa = AllocSqlDa ( pSqlDa->sqld );
  208.         
  209.         EXEC SQL
  210.         PREPARE stmt INTO :*pSqlDa FROM :pszSqlCommandBuffer;
  211.         
  212.         pSqlProcess->pBindVar = malloc (sizeof(USHORT) + (pSqlDa->sqld * sizeof (BINDTYPE)) );
  213.     }
  214.     
  215.     pSqlProcess->pSqlDa = pSqlDa;
  216.     
  217.     strcpy ( pSqlProcess->pszCmdBuf, "" );
  218.  
  219.     if ( sqlca.sqlcode == 0 )
  220.         return TRUE;
  221.     
  222.     return FALSE;
  223. }
  224.  
  225.  
  226.  
  227. /****************************************************************************/
  228. /*
  229.     FUNCTION:    SqlBindByNum ( )
  230.     
  231.     DESCRIPTION: 
  232.     
  233.     PARAMETERS:  
  234.  
  235.     RETURNS:     
  236. */
  237. /****************************************************************************/
  238.  
  239. VOID CEXPENTRY SqlBindByNum ( PSQLPROCESS pSqlProcess, USHORT usColNum, PVOID pVar, SHORT sBindType )
  240. {
  241.     pSqlProcess->pBindVar->pBindType[usColNum-1].pBindAddress = pVar;
  242.     pSqlProcess->pBindVar->pBindType[usColNum-1].sBindType    = sBindType;
  243. }
  244.  
  245.  
  246.  
  247. /****************************************************************************/
  248. /*
  249.     FUNCTION:    SqlBindByName ( )
  250.     
  251.     DESCRIPTION: 
  252.     
  253.     PARAMETERS:  
  254.  
  255.     RETURNS:     
  256. */
  257. /****************************************************************************/
  258.  
  259. VOID CEXPENTRY SqlBindByName ( PSQLPROCESS pSqlProcess, PSZ pszColName, PVOID pVar, SHORT sBindType )
  260. {
  261.     pSqlProcess;
  262.     pszColName;
  263.     pVar;
  264.     sBindType;
  265. }
  266.  
  267.  
  268.  
  269.  
  270. /****************************************************************************/
  271. /*
  272.     FUNCTION:    SqlResults ( )
  273.     
  274.     DESCRIPTION: 
  275.     
  276.     PARAMETERS:  
  277.  
  278.     RETURNS:     
  279. */
  280. /****************************************************************************/
  281.  
  282. BOOL CEXPENTRY SqlResults ( PSQLPROCESS pSqlProcess )
  283. {
  284.     pSqlProcess;
  285.  
  286.     return TRUE;
  287. }
  288.  
  289.  
  290. BOOL CEXPENTRY SqlOpenCursor  ( PSQLPROCESS pSqlProcess )
  291. {
  292.     EXEC SQL DECLARE c1 CURSOR FOR stmt;
  293.     EXEC SQL OPEN c1;
  294.     
  295.     AllocRow ( pSqlProcess->pSqlDa );
  296.     
  297.     if ( sqlca.sqlcode == 0 )
  298.         return TRUE;
  299.     
  300.     return FALSE;
  301. }
  302.  
  303. BOOL CEXPENTRY SqlCloseCursor ( PSQLPROCESS pSqlProcess )
  304. {   
  305.     EXEC SQL CLOSE c1;
  306.     
  307.     FreeRow   ( pSqlProcess->pSqlDa );
  308.     FreeSqlDa ( pSqlProcess->pSqlDa );
  309.     
  310.     return SqlCommit ( pSqlProcess );
  311. }
  312.  
  313.  
  314.  
  315. /****************************************************************************/
  316. /*
  317.     FUNCTION:    SqlFetchRow ( )
  318.     
  319.     DESCRIPTION: 
  320.     
  321.     PARAMETERS:  
  322.  
  323.     RETURNS:     
  324. */
  325. /****************************************************************************/
  326.  
  327.  
  328. BOOL CEXPENTRY SqlFetchRow ( PSQLPROCESS pSqlProcess )
  329. {   
  330.     PSQLDA pSqlDa;
  331.     
  332.     pSqlDa = pSqlProcess->pSqlDa;
  333.     
  334.     EXEC SQL FETCH c1 USING DESCRIPTOR :*pSqlDa;
  335.     BindRow ( pSqlProcess );
  336.     
  337.     if ( sqlca.sqlcode == NOTFOUND )
  338.         return FALSE;
  339.     else
  340.         return TRUE;
  341.     
  342.     return FALSE;
  343. }
  344.  
  345.  
  346. BOOL CEXPENTRY SqlCommit ( PSQLPROCESS pSqlProcess )
  347. {
  348.     EXEC SQL COMMIT WORK;
  349.     
  350.     if ( sqlca.sqlcode == 0 )
  351.         return TRUE;
  352.     
  353.     return FALSE;
  354. }
  355.  
  356. BOOL CEXPENTRY SqlRollback ( PSQLPROCESS pSqlProcess )
  357. {
  358.     EXEC SQL ROLLBACK WORK;
  359.     
  360.     if ( sqlca.sqlcode == 0 )
  361.         return TRUE;
  362.     
  363.     return FALSE;
  364. }
  365.  
  366. BOOL CEXPENTRY SqlImport ( PSQLPROCESS pSqlProcess, PSZ pszTable, PSZ pszFile, SHORT sFileType, SHORT sInsert )
  367. {
  368.     static PSZ apszFileType[4] = {SQL_ASC, SQL_DEL, SQL_WSF, SQL_IXF};
  369.     static PSZ apszImport[4] = {"INSERT", "REPLACE", "CREATE", "CREATE_REPLACE"};
  370.     struct sqldcol *docldata;
  371.     struct sqlchar *tcolstrg;
  372.     struct sqlchar *filetmod;
  373.     short  callerac;
  374.  
  375.     docldata = (struct sqldcol *)NULL;
  376.     filetmod = (struct sqlchar *)NULL;
  377.     tcolstrg = (struct sqlchar *)malloc ( sizeof(struct sqldcol) + (128) );
  378.     callerac = 0;
  379.  
  380.     tcolstrg->length = sprintf ( tcolstrg->data, "%s INTO %s", apszImport[sInsert], pszTable );
  381.  
  382.     // Debug Code
  383.     printf ( "Debug\n");
  384.     printf ( "File Type:  %s \n", apszFileType[sFileType] );
  385.     printf ( "Import Comand : %s : %d\n", tcolstrg->data, tcolstrg->length );
  386.  
  387.     sqluimp ( pSqlProcess->szDbName, pszFile, docldata, tcolstrg,
  388.           apszFileType[sFileType], filetmod, DBSQLMSG, callerac, &sqlca );
  389.  
  390.     free ( tcolstrg );
  391.  
  392.     printf ( "SQLCODE %d\n", sqlca.sqlcode );
  393.  
  394.     if ( sqlca.sqlcode == 0 )
  395.        return TRUE;
  396.  
  397.     return FALSE;
  398. }
  399.  
  400. BOOL CEXPENTRY SqlExport ( PSQLPROCESS pSqlProcess, PSZ pszTable, PSZ pszFile, SHORT sFileType )
  401. {
  402.     static PSZ apszFileType[4] = {SQL_ASC, SQL_DEL, SQL_WSF, SQL_IXF};
  403.  
  404.     struct sqldcol *docldata;
  405.     struct sqlchar *tcolstrg;
  406.     struct sqlchar *filetmod;
  407.     short  callerac;
  408.  
  409.     docldata = (struct sqldcol *)NULL;
  410.     filetmod = (struct sqlchar *)NULL;
  411.     tcolstrg = (struct sqlchar *)malloc ( sizeof(struct sqldcol) + (128) );
  412.     callerac = 0;
  413.  
  414.     tcolstrg->length = sprintf ( tcolstrg->data, "SELECT * FROM  %s", pszTable );
  415.  
  416.     // Debug Code
  417.     printf ( "Debug\n");
  418.     printf ( "File Type:  %s \n", apszFileType[sFileType] );
  419.     printf ( "Import Comand : %s : %d\n", tcolstrg->data, tcolstrg->length );
  420.  
  421.     sqluexp ( pSqlProcess->szDbName, pszFile, docldata, tcolstrg,
  422.           apszFileType[sFileType], filetmod, DBSQLMSG, callerac, &sqlca );
  423.  
  424.     free ( tcolstrg );
  425.  
  426.     if ( sqlca.sqlcode == 0 )
  427.        return TRUE;
  428.  
  429.     return FALSE;
  430. }
  431.  
  432. USHORT  CEXPENTRY SqlGetNumberColumns ( PSQLPROCESS pSqlProcess )
  433. {
  434.     return (USHORT) pSqlProcess->pSqlDa->sqld;
  435. }
  436.  
  437. SQLCOLUMNINFO CEXPENTRY SqlGetColumnNameInfo ( PSQLPROCESS pSqlProcess, SHORT sColNum )
  438. {
  439.     SQLCOLUMNINFO SqlColInfo;
  440.     SHORT         sColNameLen;
  441.     SHORT         sColLen;
  442.     BYTE          p,s;
  443.     
  444.     sColNameLen = pSqlProcess->pSqlDa->sqlvar[sColNum].sqlname.length;
  445.     strncpy ( SqlColInfo.szColumnName, pSqlProcess->pSqlDa->sqlvar[sColNum].sqlname.data, sColNameLen );
  446.     SqlColInfo.szColumnName[sColNameLen] = '\0';
  447.     
  448.     SqlColInfo.sSqlType = pSqlProcess->pSqlDa->sqlvar[sColNum].sqltype;
  449.     
  450.     sColLen = pSqlProcess->pSqlDa->sqlvar[sColNum].sqllen;
  451.     if ( SqlColInfo.sSqlType == 484 || SqlColInfo.sSqlType == 485 )
  452.     {
  453.         p = (BYTE)(sColLen & 0x00FF);
  454.         s = (BYTE)(sColLen >> 8);
  455.         
  456.         SqlColInfo.sSqlLength =  p + s + 1;
  457.     }
  458.     else
  459.         SqlColInfo.sSqlLength = sColLen;
  460.  
  461.     return SqlColInfo;
  462. }
  463.  
  464.  
  465. PVOID CEXPENTRY  SqlCreateColumnVar   ( PSQLPROCESS pSqlProcess, SHORT sColNum )
  466. {
  467.     PSQLDA    pSqlDa;
  468.     PVOID    pVar;
  469.     USHORT    usDataLen;
  470.  
  471.     pSqlDa = pSqlProcess->pSqlDa;
  472.  
  473.     switch ( pSqlDa->sqlvar[sColNum].sqltype )
  474.     {
  475.             case 452:        // CHAR ( n )
  476.         case 453:
  477.             case 384:       // DATE
  478.             case 385:
  479.             case 388:       // TIME
  480.             case 389:
  481.             case 392:       // TIMESTAMP
  482.             case 393:
  483.          usDataLen = pSqlDa->sqlvar[sColNum].sqllen + 1;
  484.         break;
  485.  
  486.             case 448:       // VARCHAR ( n )
  487.         case 449:
  488.         break;
  489.  
  490.             case 500:       // SMALLINT
  491.         case 501:
  492.         usDataLen = sizeof ( short );
  493.  
  494.             case 496:       // INTEGER
  495.         case 497:
  496.         usDataLen = sizeof ( long );
  497.         break;
  498.  
  499.             case 480:       // FLOAT
  500.             case 481:
  501.             case 484:       // DECIMAL ( p, s )
  502.         case 485:
  503.         usDataLen = sizeof ( double );
  504.         break;
  505.     }
  506.  
  507.     return pVar;
  508. }
  509.  
  510.  
  511. VOID CEXPENTRY    SqlDeleteColumnVar   ( PSQLPROCESS pSqlProcess, PVOID pVar )
  512. {
  513.     pSqlProcess;
  514.     pVar;
  515. }
  516.  
  517.  
  518. VOID   CEXPENTRY  SqlListDatabases     ( VOID )
  519. {
  520. }
  521.  
  522.  
  523. VOID   CEXPENTRY  SqlListTables        ( PSQLPROCESS pSqlProcess )
  524. {
  525.     pSqlProcess;
  526. }
  527.  
  528.  
  529. VOID   CEXPENTRY  SqlListColumns       ( PSQLPROCESS pSqlProcess )
  530. {
  531.     pSqlProcess;
  532. }
  533.  
  534.  
  535.  
  536. PSQLDA AllocSqlDa ( int cbSqlDa )
  537. {
  538.     PSQLDA pSqlDa;
  539.     
  540.     pSqlDa = ( PSQLDA ) malloc ( SQLDASIZE ( cbSqlDa ) );
  541.  
  542.     if ( pSqlDa == NULL )
  543.     {
  544.         exit ( 8 );
  545.     }
  546.  
  547.     strncpy ( pSqlDa->sqldaid, "SQLDA   ", 8 );
  548.     pSqlDa->sqldabc = (long) SQLDASIZE ( cbSqlDa );
  549.     pSqlDa->sqln    = cbSqlDa;
  550.     pSqlDa->sqld    = 0;
  551.     
  552.     return pSqlDa;
  553. }
  554.  
  555. void FreeSqlDa ( PSQLDA pSqlDa )
  556. {
  557.     free ( pSqlDa );
  558. }
  559.  
  560. int    AllocRow     ( PSQLDA pSqlDa )
  561. {
  562.     int i;
  563.  
  564.     for ( i = 0; i < pSqlDa->sqld; i++ )
  565.     {
  566.         pSqlDa->sqlvar[i].sqldata = (PBYTE) malloc ( pSqlDa->sqlvar[i].sqllen );
  567.     
  568.         if ( pSqlDa->sqlvar[i].sqldata == NULL )
  569.         {
  570.             exit ( 8 );
  571.         }
  572.         
  573.         if ( pSqlDa->sqlvar[i].sqltype & 1 )
  574.         {
  575.             pSqlDa->sqlvar[i].sqlind = (PSHORT) malloc ( 2 );
  576.             if ( pSqlDa->sqlvar[i].sqldata == NULL )
  577.             {
  578.                 exit ( 8 );
  579.             }
  580.             
  581.             pSqlDa->sqldabc += 21;
  582.         }
  583.         
  584.         pSqlDa->sqldabc += pSqlDa->sqlvar[i].sqllen;
  585.     }
  586.  
  587.     return 0;
  588. }
  589.  
  590. void   FreeRow      ( PSQLDA pSqlDa )
  591. {
  592.     int i;
  593.  
  594.     for ( i = 0; i < pSqlDa->sqld; i++ )
  595.     {
  596.         free ( pSqlDa->sqlvar[i].sqldata );
  597.     }
  598. }
  599.  
  600.  
  601. void   BindRow      ( PSQLPROCESS pSqlProcess )
  602. {
  603.     INT         i;
  604.     SHORT       sDataLen;
  605.     PSQLDA      pSqlDa;
  606.     PCHAR       pChar;
  607.     PVARCHAR    pVarChar;
  608.     BYTE        p;
  609.     BYTE        s;
  610.     BYTE        l;
  611.     PBYTE       pData;
  612.     double      value;
  613.  
  614.     pSqlDa = pSqlProcess->pSqlDa;
  615.     
  616.     for ( i = 0; i < pSqlDa->sqld; i++ )
  617.     {
  618.         sDataLen = pSqlDa->sqlvar[i].sqllen;
  619.         
  620.         switch ( pSqlDa->sqlvar[i].sqltype )
  621.         {
  622.             case 452:        // CHAR ( n )
  623.         case 453:
  624.         *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = '\0';
  625.                 pChar = pSqlDa->sqlvar[i].sqldata;
  626.                 strncpy ( pSqlProcess->pBindVar->pBindType[i].pBindAddress, pChar, sDataLen );
  627.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress + sDataLen) = '\0';
  628.                 break;
  629.         
  630.             case 448:       // VARCHAR ( n )
  631.         case 449:
  632.         *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = '\0';
  633.                 pVarChar = (PVARCHAR)pSqlDa->sqlvar[i].sqldata;
  634.                 strncpy ( pSqlProcess->pBindVar->pBindType[i].pBindAddress, 
  635.                           pVarChar->achString, pVarChar->sVarLen );
  636.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress + pVarChar->sVarLen) = '\0';
  637.                 break;
  638.                 
  639.             case 456:       // LONG VARCHAR ( n )
  640.             case 457:
  641.                 break;
  642.         
  643.             case 500:       // SMALLINT
  644.             case 501:
  645.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = *(pSqlDa->sqlvar[i].sqldata);
  646.                 break;
  647.         
  648.             case 496:       // INTEGER
  649.             case 497:
  650.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = *(pSqlDa->sqlvar[i].sqldata);
  651.                 break;
  652.         
  653.             case 480:       // FLOAT
  654.             case 481:
  655.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = (double)*(pSqlDa->sqlvar[i].sqldata);
  656.                 break;
  657.         
  658.             case 484:       // DECIMAL ( p, s )
  659.             case 485:
  660.                 p = (BYTE)(sDataLen & 0x00FF);
  661.                 s = (BYTE)(sDataLen >> 8);
  662.                 l = (BYTE)(p + 2) / 2;
  663.                 pData = pSqlDa->sqlvar[i].sqldata;
  664.                 value = PackedToDouble ( p, s, l, pData );
  665.                 memcpy ( pSqlProcess->pBindVar->pBindType[i].pBindAddress, &value, sizeof (double) );
  666.                 break;
  667.         
  668.             case 384:       // DATE
  669.             case 385:
  670.         *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = '\0';
  671.                 pChar = pSqlDa->sqlvar[i].sqldata;
  672.                 strncpy ( pSqlProcess->pBindVar->pBindType[i].pBindAddress, pChar, sDataLen );
  673.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress + sDataLen) = '\0';
  674.                 break;
  675.         
  676.             case 388:       // TIME
  677.             case 389:
  678.         *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = '\0';
  679.                 pChar = pSqlDa->sqlvar[i].sqldata;
  680.                 strncpy ( pSqlProcess->pBindVar->pBindType[i].pBindAddress, pChar, sDataLen );
  681.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress + sDataLen) = '\0';
  682.                 break;
  683.         
  684.             case 392:       // TIMESTAMP
  685.             case 393:
  686.         *(pSqlProcess->pBindVar->pBindType[i].pBindAddress) = '\0';
  687.                 pChar = pSqlDa->sqlvar[i].sqldata;
  688.                 strncpy ( pSqlProcess->pBindVar->pBindType[i].pBindAddress, pChar, sDataLen );
  689.                 *(pSqlProcess->pBindVar->pBindType[i].pBindAddress + sDataLen) = '\0';
  690.                 break;
  691.         }
  692.     }
  693. }
  694.  
  695. double PackedToDouble ( BYTE p, BYTE s, BYTE l, PBYTE pData )
  696. {
  697.     double  ret;
  698.     char    ach[34];
  699.     PBYTE   pByte;
  700.     double  shift;
  701.     int     i;
  702.     
  703.     ach[0] = '+';
  704.     for ( pByte = pData, i = 0; i < p; i+=2 )
  705.     {
  706.         ach[i+1] = (*pByte >> 4) + 48;
  707.         ach[i+2] = (*pByte & 0x0F ) + 48;
  708.  
  709.         pByte++;
  710.     }
  711.  
  712.     ach[p+1] = '\0';
  713.     
  714.     ret = atof ( ach );
  715.     
  716.     shift = pow ( 10.0 , (double)s );
  717.     ret = ret / shift;
  718.              
  719.     return ret;
  720. }
  721.