2

从应用程序调用 SQLColAttribute 时出现 SQL_INVALID_HANDLE 错误(尝试与自行开发的 odbc 驱动程序通信)我不知道为什么句柄被声明为无效句柄,因为它是一个简单的结构,在运行时仍然有效,我检查了它。该驱动程序是非 unicode 驱动程序,我从非 unicode 测试应用程序中使用它。

驱动程序还设法设置(来自驱动程序的日志)

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 但没有什么有用的。

4

2 回答 2

3

您分配了一个语句句柄,它是 0x00355790。你准备好了。正如您在调用 SQLColAttribute 时所说的那样,这一切都出错了。该日志表明使用语句句柄正确调用了 SQLColAttribute,但随后(您的驱动程序?)使用不同的句柄再次调用了 SQLColAttribute。我的猜测是您的驱动程序中存在函数名称冲突。

于 2013-04-10T10:56:26.680 回答
2

请参阅 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

并了解这有多困难

  • >(对我来说)避免两种情况下的函数名冲突(x64/x86)
  • > (for microsoft) 编写正确的文档
于 2013-11-19T16:42:15.657 回答