2013-04-09 16 views
1

我從應用程序調用SQLColAttribute時發生SQL_INVALID_HANDLE錯誤(試圖與自己開發的odbc驅動程序通信)我不知道爲什麼句柄表示無效句柄,因爲它是一個簡單的結構,這在運行時仍然有效,先檢查一下。該驅動程序是一個非unicode驅動程序,並使用它從一個非unicode測試應用程序。微軟odbc drivermanager SQLColAttribute SQL_INVALID_HANDLE

司機還管理設置(日誌從司機)

SQLGetStmtAttr called: 
Attribute to set is: SQL_ATTR_APP_ROW_DESC 
SQLGetStmtAttr called: 
Attribute to set is: SQL_ATTR_APP_PARAM_DESC 
SQLGetStmtAttr called: 
Attribute to set is: SQL_ATTR_IMP_ROW_DESC 
SQLGetStmtAttr called: 
Attribute to set is: SQL_ATTR_IMP_PARAM_DESC 

調用SQLPrepare之前妥善

驅動程序管理日誌:

ODBC_Test  2210-151c ENTER SQLAllocHandle 
    SQLSMALLINT     1 <SQL_HANDLE_ENV> 
    SQLHANDLE   0x00000000 
    SQLHANDLE *   0x002EFCC0 

ODBC_Test  2210-151c EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS) 
    SQLSMALLINT     1 <SQL_HANDLE_ENV> 
    SQLHANDLE   0x00000000 
    SQLHANDLE *   0x002EFCC0 (0x003541C8) 

ODBC_Test  2210-151c ENTER SQLSetEnvAttr 
    SQLHENV    0x003541C8 
    SQLINTEGER     200 <SQL_ATTR_ODBC_VERSION> 
    SQLPOINTER     3 <SQL_OV_ODBC3> 
    SQLINTEGER     0 

ODBC_Test  2210-151c EXIT SQLSetEnvAttr with return code 0 (SQL_SUCCESS) 
    SQLHENV    0x003541C8 
    SQLINTEGER     200 <SQL_ATTR_ODBC_VERSION> 
    SQLPOINTER     3 <SQL_OV_ODBC3> 
    SQLINTEGER     0 

ODBC_Test  2210-151c ENTER SQLAllocHandle 
    SQLSMALLINT     2 <SQL_HANDLE_DBC> 
    SQLHANDLE   0x003541C8 
    SQLHANDLE *   0x002EFCA8 

ODBC_Test  2210-151c EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS) 
    SQLSMALLINT     2 <SQL_HANDLE_DBC> 
    SQLHANDLE   0x003541C8 
    SQLHANDLE *   0x002EFCA8 (0x00354250) 

ODBC_Test  2210-151c ENTER SQLConnectW 
    HDBC    0x00354250 
    WCHAR *    0x00352EB8 [  5] "dsn01" 
    SWORD      5 
    WCHAR *    0x55128B34 [  -3] "******\ 0" 
    SWORD      -3 
    WCHAR *    0x55128B34 [  -3] "******\ 0" 
    SWORD      -3 

ODBC_Test  2210-151c EXIT SQLConnectW with return code 0 (SQL_SUCCESS) 
    HDBC    0x00354250 
    WCHAR *    0x00352EB8 [  5] "dsn01" 
    SWORD      5 
    WCHAR *    0x55128B34 [  -3] "******\ 0" 
    SWORD      -3 
    WCHAR *    0x55128B34 [  -3] "******\ 0" 
    SWORD      -3 

ODBC_Test  2210-151c ENTER SQLAllocHandle 
    SQLSMALLINT     3 <SQL_HANDLE_STMT> 
    SQLHANDLE   0x00354250 
    SQLHANDLE *   0x002EF6F8 

ODBC_Test  2210-151c EXIT SQLAllocHandle with return code 0 (SQL_SUCCESS) 
    SQLSMALLINT     3 <SQL_HANDLE_STMT> 
    SQLHANDLE   0x00354250 
    SQLHANDLE *   0x002EF6F8 (0x00355790) 

ODBC_Test  2210-151c ENTER SQLPrepare 
    HSTMT    0x00355790 
    UCHAR *    0x00DB89C8 [  72] "select COUNTRYFR,CITYFROM,CITYTO from SPFLI where CITYFROM EQ 'NEW YORK'" 
    SDWORD     72 

ODBC_Test  2210-151c EXIT SQLPrepare with return code 0 (SQL_SUCCESS) 
    HSTMT    0x00355790 
    UCHAR *    0x00DB89C8 [  72] "select COUNTRYFR,CITYFROM,CITYTO from SPFLI where CITYFROM EQ 'NEW YORK'" 
    SDWORD     72 

ODBC_Test  2210-151c ENTER SQLColAttribute 
    SQLHSTMT   0x00355790 
    SQLSMALLINT     1 
    SQLSMALLINT     14 <SQL_DESC_TYPE_NAME> 
    SQLPOINTER   0x002EF6B0 
    SQLSMALLINT     50 
    SQLSMALLINT *  0x002EF6A4 
    SQLPOINTER   0x00000000 (NYI) 

ODBC_Test  2210-151c ENTER SQLColAttribute 
    SQLHSTMT   0x00C05200 
    SQLSMALLINT     1 
    SQLSMALLINT     14 <SQL_DESC_TYPE_NAME> 
    SQLPOINTER   0x002EF6B0 
    SQLSMALLINT     50 
    SQLSMALLINT *  0x002EF6A4 
    SQLPOINTER   0x00000000 (NYI) 

ODBC_Test  2210-151c EXIT SQLColAttribute with return code -2 (SQL_INVALID_HANDLE) 
    SQLHSTMT   0x00C05200 
    SQLSMALLINT     1 
    SQLSMALLINT     14 <SQL_DESC_TYPE_NAME> 
    SQLPOINTER   0x002EF6B0 
    SQLSMALLINT     50 
    SQLSMALLINT *  0x002EF6A4 
    SQLPOINTER   0x00000000 (NYI) 

ODBC_Test  2210-151c EXIT SQLColAttribute with return code -2 (SQL_INVALID_HANDLE) 
    SQLHSTMT   0x00355790 
    SQLSMALLINT     1 
    SQLSMALLINT     14 <SQL_DESC_TYPE_NAME> 
    SQLPOINTER   0x002EF6B0 
    SQLSMALLINT     50 
    SQLSMALLINT *  0x002EF6A4 
    SQLPOINTER   0x00000000 (NYI) 

測試程序是非常簡單的:

SQLHANDLE hEnv ; 

SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv) ; 

SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0) ; 

SQLHANDLE hConn ; 

SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConn); 


SQLCHAR* dsnName = (SQLCHAR*)"dsn01" ; // MUST BE THE SAME 
SQLCHAR* userid = (SQLCHAR*)"nodata\0"; 
SQLCHAR* password = (SQLCHAR*)"nodata\0"; 

SQLConnect(

hConn, 
dsnName, 
5, 
userid, 
SQL_NTS, 
password, 
SQL_NTS); 


HSTMT hStmt ; 
SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt) ; 

SQLCHAR* query = (SQLCHAR*)"select COUNTRYFR,CITYFROM,CITYTO from SPFLI where CITYFROM EQ 'NEW YORK'"; 

SQLPrepare(hStmt,query,strlen((const char*)query)); 

SQLCHAR TypeName[50]; 
SQLSMALLINT TypeNameLen; 

SQLColAttribute((SQLHSTMT)hStmt,1,SQL_DESC_TYPE_NAME,TypeName, sizeof(TypeName),&TypeNameLen,NULL); 

任何人都知道什麼會導致SQLColAttribute返回SQL_INVALID_HANDLE?我讀過msdn,但沒有用處。

回答

2

您分配了一個語句句柄,它是0x00355790。你準備好了。當您調用SQLColAttribute時,它會出錯。該日誌表明SQLColAttribute與語句句柄一起被正確調用,但隨後(您的驅動程序?)再次使用不同的句柄調用SQLColAttribute。我的猜測是你的驅動程序中有一個函數名衝突。

+0

感謝您的支持他的建議,但我100%確定SQLColAttribute不會從我的驅動程序調用。這是drivermanagers日誌,您可以在這裏看到,因爲它將我的1個SQLColAttribute調用從測試應用程序轉換爲空中的2個調用(其中一個調用仍然有效的語句句柄,另一個調用自己的包裝句柄)返回sql_invalid_handle。如果司機管理員會打入我的司機,我可以在司機日誌中看到它。我錯了嗎? – 2013-04-10 17:34:18

+1

我意識到這是一個驅動程序管理器日誌。但是,使用正常工作的驅動程序時,應用程序對SQLColAttribute的調用只會記錄一次(確實是兩次,但一次是入口,一次是退出)。您需要查看第二個SQLColAttribute調用中傳遞的句柄(不正確的句柄),並查看誰創建了它或者該位置處的內容。日誌defintely使它看起來像SQLColAttribute被調用兩次,就好像你的驅動程序正在用它自己的句柄調用它。 – bohica 2013-04-10 18:10:43

+0

我剛剛在Windows上使用我的工作ODBC驅動程序(我寫過)再次嘗試過它,並且一次調用SQLColAttribute以正確的句柄結束它的單個日誌條目。偶爾我的驅動程序需要調用它自己的ODBC API而不是通過驅動程序管理器,並且爲了達到這個目的,它有2個入口點SQLxxx,驅動程序管理器調用這個入口點,但這只是簡單地調用_SQLxxx,因此,如果我的驅動程序想繞過驅動程序管理器,可以調用_SQLxxx 。 – bohica 2013-04-10 18:17:35

1

看到這個聲明在sqlucode.h:

// UNICODE versions 
#ifdef _WIN64 
SQLRETURN SQL_API SQLColAttributeW 
(
    SQLHSTMT  hstmt, 
    SQLUSMALLINT iCol, 
    SQLUSMALLINT iField, 
    _Out_writes_bytes_opt_(cbDescMax) 
    SQLPOINTER  pCharAttr, 
    SQLSMALLINT  cbDescMax, 
    _Out_opt_ 
    SQLSMALLINT  *pcbCharAttr, 
    _Out_opt_ 
    SQLLEN   *pNumAttr 
); 
#else 
SQLRETURN SQL_API SQLColAttributeW(
    SQLHSTMT  hstmt, 
    SQLUSMALLINT iCol, 
    SQLUSMALLINT iField, 
    _Out_writes_bytes_opt_(cbDescMax) 
    SQLPOINTER  pCharAttr, 
    SQLSMALLINT  cbDescMax, 
    _Out_opt_ 
    SQLSMALLINT  *pcbCharAttr, 
    _Out_opt_ 
    SQLPOINTER  pNumAttr); 
#endif 

和理解是多麼困難

  • >(對我來說),以避免函數名稱衝突在這兩種情況下(64/x86)
  • >(用於微軟)寫入正確的文檔