1

我正在使用node-odbc将基于 Node.js 的应用程序连接到旧版 IBM DB2 数据库。

  • 在 Windows 7 上
  • DB2 ODBC 驱动程序是 32 位的,因此 node-odbc 二进制文件是用node-gyp clean configure build --arch=ia32 --msvs_version=2015
  • 32 位 Node.js 4.4.5

这主要工作正常。但是,由于以下问题,我目前在 node-odbc 二进制文件( binding.gyp 中的标志 UNICODE )禁用了 Unicode :

如果我启用 UNICODE,我可以

  1. 使用简单的 SQL 语句(如 query = select * from sysibm.sysdummy1)正确检索数据
  2. 使用非字符串参数绑定运行查询(如 query = select * from syscat.tables where tableid = ?、 bindings = [0];

但是,如果我使用字符串参数(如 query = select * from syscat.tables where tabname = ?、 bindings = ['SYSDUMMY1'])运行查询,则 ODBC 驱动程序会抛出错误消息

{ [错误:[IBM][CLI Driver] CLI0002W 数据被截断。SQLSTATE=01004] 错误:[ { message: '[IBM][CLI Driver] CLI0002W 数据被截断。SQLSTATE=01004',状态:'01004' } ],错误:'[node-odbc] SQL_ERROR',消息:'[IBM][CLI Driver] CLI0002W 数据被截断。SQLSTATE=01004',状态:'01004' }

在 IBM 文档中的解释对我没有帮助。

我查看了相关 node-odbc 代码中启用 UNICODE 的片段,这些片段将字符串写入缓冲区,缓冲区将被传递给 ODBC 驱动程序:

#ifdef UNICODE
      params[i].ParameterType     = SQL_WVARCHAR;
      params[i].BufferLength      = (length * sizeof(uint16_t)) + sizeof(uint16_t);
#else
      params[i].ParameterType     = SQL_VARCHAR;
      params[i].BufferLength      = string->Utf8Length() + 1;
#endif
      params[i].ParameterValuePtr = malloc(params[i].BufferLength);
      params[i].StrLen_or_IndPtr  = SQL_NTS;//params[i].BufferLength;

#ifdef UNICODE
      string->Write((uint16_t *) params[i].ParameterValuePtr);
#else
      string->WriteUtf8((char *) params[i].ParameterValuePtr);
#endif

显然,string->Write将带有空终端的字符串写入缓冲区ParameterValuePtrSQL_NTS表示以空值结尾的字符串(请参阅IBM 文档中对StrLen_or_IndPtr的解释)。

从错误消息来看,我假设缓冲区的大小不正确,其计算公式为(length * sizeof(uint16_t)) + sizeof(uint16_t)(Unicode 字符的字节长度 + 1 个附加字符,空终止符):

  1. 要么它太小,所以 ODBC 驱动程序找不到终止字符串的空字符
  2. 或者太大,所以驱动程序可能会抱怨空字符出现在缓冲区结束之前。这真的是一个假设!

所以:我想知道如何更正代码,以便可以将类似字符串的参数传递给 ODBC 驱动程序。有任何想法吗?

4

0 回答 0