0 Replies Latest reply: Nov 29, 2012 1:40 AM by 976908 RSS

    ODBC呼び出しで、Access violation発生

    976908
      windows環境で、以下のようにTIMESTAMP項目とBLOB項目を定義し、TIMESTAMP項目に誤った内容を設定してSQL_C_WCHAR (unicode)で格納しようとすると、
      SQLExecuteの呼び出しで、Unhandled exception at .... in .... 0xc000005: Access vioretion reading location 0x00000000.
      が発生する。

      CREATE TABLE TABLE1
      (
      TIME1 TIMESTAMP(6),
      BLOB1 BLOB
      )

      // Bug.cpp : Defines the entry point for the console application.
      //

      #include "stdafx.h"
      #include <Windows.h>
      #include <sql.h>
      #include <sqlext.h>
      #include <conio.h>

      void ShowError(SQLSMALLINT handleType, SQLHANDLE handle){
           SQLCHAR state[6];
           SQLINTEGER code;
           SQLCHAR msg[500];
           SQLSMALLINT msgLen;

           msg[0] = '\0';
           SQLGetDiagRec(handleType, handle, 1, state, &code, msg, sizeof(msg) / sizeof(SQLCHAR), &msgLen);
           printf_s("State:%s | Error:%s\n", state, msg);
      }

      /*
                TABLE1
                (
                     TIME1 TIMESTAMP(6),
                     BLOB1 BLOB
                )
      */
      int tmain(int argc, TCHAR* argv[])
      {
           SQLHENV henv;
           SQLHDBC hdbc;
           SQLHSTMT hstmt;

           if(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv) != SQL_SUCCESS)
           {
                return -1;
           }

           if(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_ENV, henv);
                return -1;
           }

           if(SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_ENV, henv);
                return -1;
           }

           if(SQLConnect(
                hdbc,
                (SQLCHAR*)"test_remote_oracle_datasource",
                SQL_NTS,
                (SQLCHAR*)"SYSTEM",
                SQL_NTS,
                (SQLCHAR*)"DTRii2012$",
                SQL_NTS) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_DBC, hdbc);
                return -1;
           }

           if(!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt)))
           {
                ShowError(SQL_HANDLE_DBC, hdbc);
                return -1;
           }

           SQLINTEGER cbMaxValues[2];
           SQLINTEGER indicates[2];
           wchar_t time1[29] = L"xx12-09-28 11:00:00.00000000"; /* invalid datetime */
           char blob1[11] = "1234567890";

           cbMaxValues[0] = 19 * sizeof(wchar_t);
           cbMaxValues[1] = strlen(blob1);

           indicates[0] = 19 * sizeof(wchar_t);
           indicates[1] = strlen(blob1);

           if(SQLPrepare(hstmt, (SQLCHAR*)"INSERT INTO TABLE1 (TIME1, BLOB1) VALUES (?, ?)", SQL_NTS) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_STMT, hstmt);
           }

           if(SQLBindParameter(
                hstmt,
                1,
                SQL_PARAM_INPUT,
                SQL_C_WCHAR,
                SQL_TYPE_TIMESTAMP,
                19,
                6,
                time1,
                cbMaxValues[0],
                &indicates[0]) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_STMT, hstmt);
           }

           if(SQLBindParameter(
                hstmt,
                2,
                SQL_PARAM_INPUT,
                SQL_C_BINARY,
                SQL_BINARY,
                2147483647, /* column size of blob */
                0,
                blob1,
                cbMaxValues[1],
                &indicates[1]) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_STMT, hstmt);
           }

           if(SQLExecute(hstmt) != SQL_SUCCESS)
           {
                ShowError(SQL_HANDLE_STMT, hstmt);
           }

           SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
           SQLDisconnect(hdbc);
           SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
           SQLFreeHandle(SQL_HANDLE_ENV, henv);

           _getch();
           return 0;
      }