dobrizaj

odbc

Jun 10th, 2014
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.56 KB | None | 0 0
  1. // odbc_1.cpp: определяет точку входа для консольного приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  
  6. #include <iostream>
  7. #include <windows.h>
  8. #include <sqltypes.h>
  9. #include <sql.h>
  10. #include <sqlext.h>
  11.  
  12. struct TimeStamp
  13. {
  14.     short int year;
  15.     short int month;
  16.     short int day;
  17.     short int hour;
  18.     short int minute;
  19.     short int second;
  20.     unsigned long int fraction;
  21. };
  22.  
  23. struct tagSQLGUID {
  24.     DWORD Data1;
  25.     WORD Data2;
  26.     WORD Data3;
  27.     BYTE Data4[8];
  28. };
  29.  
  30.  
  31.  
  32. void PrintData(void* DataPtr, SQLSMALLINT CTypeArray, SQLINTEGER DataLenght);
  33. SQLSMALLINT GetDefaultCType(SQLINTEGER SQLType);
  34.  
  35.  
  36. #define ALIGNSIZE 4
  37. #define ALIGNBUF(Length) Length % ALIGNSIZE ? \
  38.     Length + ALIGNSIZE - (Length % ALIGNSIZE) : Length
  39.  
  40.  
  41. int _tmain(int argc, _TCHAR* argv[])
  42. {
  43.     // Initialize the environment, connection, statement handles.
  44.     SQLHENV env;
  45.     SQLHDBC dbc;
  46.     SQLHSTMT stmt;
  47.  
  48.     SQLRETURN ret;
  49.        
  50.     SQLWCHAR      SqlState[6], Msg[SQL_MAX_MESSAGE_LENGTH*2];
  51.     SQLINTEGER    NativeError;
  52.     SQLSMALLINT   i, MsgLen;
  53.  
  54.  
  55.     ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
  56.     ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
  57.  
  58.     ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
  59.     ret = SQLSetConnectAttr(dbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);
  60.     //ret = SQLDriverConnectW(dbc, NULL, L"DRIVER={SQL Server};SERVER=name1;DATABASE=db1;UID=sa;PWD=pass;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
  61.     ret = SQLDriverConnectW(dbc, NULL, L"DRIVER={MySQL ODBC 5.3 UNICODE Driver}; SERVER = localhost; Port = 3307; DATABASE = worddb; UID = root; PWD = usbw; Option = 3", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
  62.  
  63.  
  64.     if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))
  65.     {
  66.         std::cout << "Prepare statements" << std::endl;
  67.         ret = SQLPrepare(stmt, L"SELECT * FROM words", SQL_NTSL);
  68.         //ret = SQLPrepare(stmt, L"SELECT TOP 3 FirewallLog.* FROM FirewallLog", SQL_NTSL);
  69.         if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
  70.         {
  71.             std::cout << "Execute" << std::endl;
  72.             ret = SQLExecute(stmt);
  73.             if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
  74.             {
  75.                 std::cout << "  retrieve column count" << std::endl;
  76.                 // вот тут необходимо узнать количество колонок
  77.                 // их размер и тип данных
  78.                 SQLSMALLINT    siNumCols;
  79.                 SQLSMALLINT*   CTypeArray(nullptr), i;
  80.                 SQLINTEGER *   ColLenArray(nullptr), *OffsetArray(nullptr), SQLType;
  81.                 SQLINTEGER * RecLenArray(nullptr);
  82.                 void* DataPtr(nullptr);
  83.  
  84.                 ret = SQLNumResultCols(stmt, &siNumCols);
  85.                 std::cout << "   count siNumCols: " << siNumCols << std::endl;
  86.  
  87.                 CTypeArray = (SQLSMALLINT *)malloc(siNumCols * sizeof(SQLSMALLINT));
  88.                 ColLenArray = (SQLINTEGER *)malloc(siNumCols * sizeof(SQLINTEGER));
  89.                 RecLenArray = (SQLINTEGER *)malloc(siNumCols * sizeof(SQLINTEGER));
  90.                 OffsetArray = (SQLINTEGER *)malloc(siNumCols * sizeof(SQLINTEGER));
  91.                
  92.                 OffsetArray[0] = 0;
  93.                 for (i = 0; i < siNumCols; i++)
  94.                 {
  95.                     // тип колонки
  96.                     SQLColAttribute(stmt, ((SQLUSMALLINT)i) + 1, SQL_DESC_TYPE, NULL, 0, NULL, (SQLPOINTER)&SQLType);
  97.                     CTypeArray[i] = GetDefaultCType(SQLType);
  98.  
  99.                     // вычисляем размер колонки
  100.                     SQLColAttribute(stmt, ((SQLUSMALLINT)i) + 1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &ColLenArray[i]);
  101.  
  102.                     ColLenArray[i] = ALIGNBUF(ColLenArray[i]);
  103.                     if (i)
  104.                         OffsetArray[i] = OffsetArray[i - 1] + ColLenArray[i - 1];
  105.  
  106.                     std::cout << i << ". SQLType: " << SQLType << " CType: " << CTypeArray[i] << " Length: " << ColLenArray[i] << "; OffsetArray[i]= " << OffsetArray[i] << std::endl;
  107.                 }
  108.  
  109.                 // выделяем память под данные
  110.                 DataPtr = malloc(OffsetArray[siNumCols - 1] + ColLenArray[siNumCols - 1]);
  111.                
  112.                     for (i = 0; i < siNumCols; i++)
  113.                         SQLBindCol(stmt,
  114.                         ((SQLUSMALLINT)i) + 1,
  115.                         CTypeArray[i],
  116.                         (BYTE *)DataPtr + OffsetArray[i],
  117.                         ColLenArray[i],
  118.                         &RecLenArray[i]);
  119.  
  120.                
  121.                     while ((ret = SQLFetch(stmt)) != SQL_NO_DATA) {
  122.                         for (i = 0; i < siNumCols; i++) {                            
  123.                             PrintData(((BYTE*)DataPtr + OffsetArray[i]), CTypeArray[i], RecLenArray[i]);                            
  124.                             std::cout << " | ";
  125.                         }
  126.                         std::cout << "\n";
  127.                     }
  128.                                        
  129.                     free(CTypeArray);
  130.                     free(ColLenArray);
  131.                     free(OffsetArray);
  132.                                        
  133.                     free(DataPtr);
  134.                
  135.             }
  136.             else
  137.             {
  138.                 i = 1;
  139.                 while ((ret = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, i, SqlState, &NativeError,
  140.                     Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) {                    
  141.                     std::wcout << SqlState << " | " << NativeError << " | " << Msg << std::endl;
  142.                     i++;
  143.                 }
  144.             }
  145.  
  146.             SQLFreeStmt(stmt, SQL_DROP);
  147.         }
  148.         else
  149.         {
  150.             std::cout << "Failed to prepare" << std::endl;
  151.         }
  152.     }
  153.     else
  154.     {
  155.         std::cout << "Failed to connect" << std::endl;
  156.     }
  157.  
  158.  
  159.     /*close handle*/
  160.     if (stmt)
  161.     {
  162.         SQLFreeHandle(SQL_HANDLE_STMT, stmt);
  163.         stmt = NULL;
  164.     }
  165.  
  166.     if (dbc)
  167.     {
  168.         SQLDisconnect(dbc);
  169.         SQLFreeHandle(SQL_HANDLE_DBC, dbc);
  170.         dbc = NULL;
  171.     }
  172.  
  173.     if (env)
  174.     {
  175.         SQLFreeHandle(SQL_HANDLE_ENV, env);
  176.         env = NULL;
  177.     }
  178.    
  179.  
  180.     std::cout << "Press enter to exit.";
  181.     std::cin.get();
  182.  
  183.     return 0;
  184. }
  185.  
  186.  
  187. void PrintData(void* DataPtr, SQLSMALLINT CTypeArray, SQLINTEGER DataLenght)
  188. {
  189.     switch (CTypeArray)
  190.     {
  191.     case SQL_C_CHAR:
  192.     case SQL_C_WCHAR:    
  193.     {
  194.                                  char *ch = (char*)DataPtr;
  195.                                  for (int i = 0; i < DataLenght; ++i)
  196.                                      std::cout << ch[i];
  197.     }
  198.         break;
  199.     case SQL_C_TYPE_DATE:
  200.     case SQL_C_TYPE_TIME:
  201.     case SQL_C_TYPE_TIMESTAMP:
  202.     {
  203.                                  TimeStamp *ts = (TimeStamp *)DataPtr;
  204.                                  std::cout << ts->day << "-" << ts->month << "-" << ts->year << " " << ts->hour << ":" << ts->minute << ":" << ts->minute;
  205.     }
  206.         break;
  207.     case SQL_C_GUID:
  208.     {
  209.                        tagSQLGUID *g = (tagSQLGUID*)DataPtr;
  210.                        std::cout << g->Data1 << "-" << g->Data2 << "-" << g->Data3 << "-" << g->Data4;
  211.     }
  212.         break;
  213.     case SQL_C_SHORT:
  214.         std::cout << *(int*)DataPtr;
  215.         break;
  216.     case SQL_C_LONG:
  217.         std::cout << *(long*)DataPtr;
  218.         break;
  219.     default:
  220.         std::cout << "Unknown";
  221.     }
  222. }
  223.  
  224.  
  225. SQLSMALLINT GetDefaultCType(SQLINTEGER SQLType)
  226. {
  227.  
  228.     switch (SQLType)
  229.     {
  230.     case SQL_CHAR:
  231.     case SQL_VARCHAR:
  232.     case SQL_LONGVARCHAR:
  233.     case SQL_WCHAR:
  234.     case SQL_WLONGVARCHAR:
  235.         return SQL_C_CHAR;
  236.     case SQL_TINYINT:
  237.         return SQL_C_CHAR;
  238.     case SQL_SMALLINT:
  239.         return SQL_C_SHORT;
  240.     case SQL_INTEGER:
  241.         return SQL_C_LONG;
  242.     case SQL_BIGINT:
  243.         return SQL_C_UBIGINT;
  244.     case SQL_REAL:
  245.         return SQL_C_FLOAT;
  246.     case SQL_FLOAT:
  247.     case SQL_DOUBLE:
  248.         return SQL_C_DOUBLE;
  249.     case SQL_DECIMAL:
  250.     case SQL_BIT:
  251.     case SQL_BINARY:
  252.     case SQL_VARBINARY:
  253.     case SQL_LONGVARBINARY:
  254.     case SQL_NUMERIC:
  255.         return SQL_C_FLOAT;
  256.     case SQL_TYPE_DATE:
  257.     case SQL_TYPE_TIME:
  258.     case SQL_INTERVAL_YEAR:
  259.     case SQL_INTERVAL_MONTH:
  260.         return SQL_C_CHAR;
  261.     case SQL_TYPE_TIMESTAMP:
  262.     case SQL_DATETIME:
  263.         return SQL_C_TYPE_TIMESTAMP;
  264.  
  265.     case SQL_GUID:
  266.         return SQL_C_GUID;
  267.     default:
  268.         return SQL_C_CHAR;
  269.     }
  270. }
Advertisement
Add Comment
Please, Sign In to add comment