IBM DB2 ODBC驱动程序为ODBC API SQLGetInfo()返回错误的值

IBM DB2 ODBC驱动程序为ODBC API SQLGetInfo()返回错误的值,db2,odbc,Db2,Odbc,调用以下ODBC API时,IBM DB2 ODBC驱动程序返回错误的值: void Test() { // Allocate environment handle. SQLHENV environmentHandle; SQLRETURN returnCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environmentHandle); // Set ODBC version to 3.8

调用以下ODBC API时,IBM DB2 ODBC驱动程序返回错误的值:

void Test()
{
   // Allocate environment handle.
   SQLHENV environmentHandle;
   SQLRETURN returnCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environmentHandle);

   // Set ODBC version to 3.8
   returnCode = SQLSetEnvAttr(environmentHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, 0);

   // Allocate connection handle.
   SQLHDBC connectionHandle;
   returnCode = SQLAllocHandle(SQL_HANDLE_DBC, environmentHandle, &connectionHandle);

   // Connect to the database.
   TCHAR dsn[] = _T("DSN=ODBCDB2"), connStringOut[100] = _T("");
   SQLSMALLINT connStringOutSize = 0;
   returnCode = SQLDriverConnect(connectionHandle, NULL, (SQLTCHAR *)dsn, _tcslen(dsn), (SQLTCHAR*)connStringOut, sizeof(connStringOut) / sizeof(TCHAR), &connStringOutSize, SQL_DRIVER_NOPROMPT);
   // connStringOut = L"DSN=ODBCDB2;UID=<userid>;PWD=<password>;DBALIAS=TESTDB"

   // Retrieve the quote character.
   TCHAR quoteValue[15] = _T("");
   SQLSMALLINT infoValue = 0;
   returnCode = SQLGetInfo(connectionHandle, SQL_IDENTIFIER_QUOTE_CHAR, &quoteValue, sizeof(quoteValue), &infoValue);
   // quoteValue = L"03.80"
   // infoValue = 10
}
void测试()
{
//分配环境句柄。
SQLHENV环境句柄;
SQLRETURN-returnCode=SQLAllocHandle(SQL\u HANDLE\u ENV、SQL\u NULL\u HANDLE和environmentHandle);
//将ODBC版本设置为3.8
returnCode=SQLSetEnvAttr(environmentHandle,SQL\u ATTR\u ODBC\u VERSION,(SQLPOINTER)SQL\u OV\u ODBC3\u 80,0);
//分配连接句柄。
SQLHDBC连接句柄;
returnCode=SQLAllocHandle(SQL\u HANDLE\u DBC、environmentHandle和connectionHandle);
//连接到数据库。
TCHAR dsn[]=\u T(“dsn=ODBCDB2”),connStringOut[100]=\u T(“”);
SQLSMALLINT connStringOutSize=0;
returnCode=SQLDriverConnect(connectionHandle,NULL,(SQLTCHAR*)dsn,_-tcslen(dsn),(SQLTCHAR*)connStringOut,sizeof(connStringOut)/sizeof(TCHAR),&connStringOutSize,SQL\u-DRIVER\u-NOPROMPT);
//connStringOut=L“DSN=ODBCDB2;UID=;PWD=;DBALIAS=TESTDB”
//检索引号字符。
TCHAR quoteValue[15]=_T(“”);
SQLSMALLINT infoValue=0;
returnCode=SQLGetInfo(connectionHandle、SQL标识符CHAR、quoteValue、sizeof(quoteValue)、infoValue);
//quoteValue=L“03.80”
//infoValue=10
}
API调用
SQLGetInfo()
应返回双引号字符(“),单引号字符(”)等引号字符。相反,它返回的
03.80
不正确。此值看起来是ODBC驱动程序版本

更新:如果
sqlsetenvatr()
中的参数
SQL_OV_ODBC3_80
更改为
SQL_OV_ODBC3
SQL_OV_ODBC2
,则引号字符是正确的(“)。看起来是版本特定的问题

环境详情:

  • IBM DB2 v11.5.0.1077
  • IBM DB2 ODBC驱动程序v11.5.0.1077(32位)
  • ODBC v3.8
  • VC++(Visual Studio 2017)
  • Windows 10 64位
非常感谢您的帮助。 谢谢

如果使用该版本编译,DB2V11.5“sqlext.h”已经有了SQL_SPEC_MAJOR(3)和SQL_SPEC_MINOR(“80”),这意味着不必在代码中显式设置该ODBC版本,因为不管文档如何建议,该版本可能是V11.5的默认版本

该文件不充分,因为它有无保留意见:

“如果将SQL_ATTR_ODBC_VERSION属性设置为SQL_OV_ODBC3_80 (值380),CLI返回“03.80”

即使您查询的是
SQL\u IDENTIFIER\u QUOTE\u CHAR
,代码也会返回该值。我可以在对代码进行微小更改后,在VS2019和V11.5中重现该症状,以正确初始化TCHAR阵列。对我来说,这似乎是不受欢迎的行为,但只有IBM可以决定它是否有缺陷

我建议您就这个特定问题向IBMDB2支持部门提出问题


正如您所观察到的,解决方法是编译/链接V11.5头文件/库,而不显式地将ODBC版本设置为SQL_ATTR_ODBC_version(即省略代码
returnCode=SQLSetEnvAttr(environmentHandle,SQL_ATTR_ODBC_version,(SQLPOINTER)SQL_OV_ODBC3_80,0);
)。在这种情况下,引号字符的
SQLGetInfo
返回正确的值。

它对我来说工作正常(Win10 64位,v11.5.0.1088),返回“。请检查工具链和构建,并建议SQLGetInfo的最后一个参数是有效指针,您应该检查其返回值(在我的情况下,返回值为1)谢谢,mao!我刚刚创建了一个新的示例应用程序(32位),问题仍然存在。此外,由于某些原因,64位驱动程序无法加载。根据我的建议,通过最后(第五)个参数返回的值是多少?是10。谢谢!谢谢mao!问题是,如果没有显式设置ODBC版本,那么调用
SQLAllocHandle(SQL\u HANDLE\u DBC、environmentHandle和connectionHandle)
返回错误
[Microsoft][ODBC驱动程序管理器]函数序列错误
。如果忽略显式设置ODBC版本,我不会观察到这种行为,相反,连接成功,我可以打印出GetInfo返回的正确引号字符。您的描述中可能缺少什么?