本文包含 Linux 和 macOS 上的 Microsoft ODBC Driver for SQL Server 13、13.1、17 和 18 的已知问题列表。 它还包含用于排查连接问题的步骤。
Known issues
有关其他问题,请参阅 SQL Server 驱动程序博客。
由于系统库限制,Alpine Linux 支持较少的字符编码和区域设置。 例如,
en_US.UTF-8不可用。 有关详细信息,请参阅musl libc- 与glibc的功能差异。Windows、Linux 和 macOS 可以采用不同方式转换来自专用区 (PUA) 或最终用户定义的字符 (EUDC) 的字符。 在服务器上执行的 Transact-SQL 内的转换将使用 Windows 转换库。 驱动程序中的转换使用 Windows、Linux 或 macOS 转换库。 执行这些转换时,每个库都可以生成不同的结果。 有关详细信息,请参阅最终用户定义的字符和专用区字符。
如果客户端采用 UTF-8 编码,驱动程序管理器不会始终将 UTF-8 正确转换为 UTF-16。 目前,当字符串中的一个或多个字符不是有效的 UTF-8 字符时,会发生数据损坏。 ASCII 字符已正确映射。 当调用 SQLCHAR 版本的 ODBC API(例如 SQLDriverConnectA)时,驱动程序管理器尝试此转换。 驱动程序管理器在调用 ODBC API 的 SQLWCHAR 版本(例如 SQLDriverConnectW)时不会尝试此转换。
ColumnSize 参数
SQLBindParameter是指 SQL 类型中的字符数,而 BufferLength 是应用程序缓冲区中的字节数。 但是,如果 SQL 数据类型为 varchar(n) 或 char(n),应用程序会将参数SQL_C_CHAR绑定到 C 类型以及SQL_CHARSQL_VARCHARSQL 类型,并且客户端的字符编码为 UTF-8,即使String data, right truncation的值与服务器上的数据类型大小保持一致,也可能从驱动程序中收到错误。 发生此错误,因为字符编码之间的转换可能会更改数据的长度。 例如,右撇号字符(U+2019)在 CP-1252 中编码为单字节0x92,但在 UTF-8 中为 3 字节序列0xE2 0x80 0x99。
例如,如果编码为 UTF-8,并且你为 out 参数同时为 BufferLength 和 ColumnSizeSQLBindParameter 指定 1,然后尝试检索存储在 char(1) 服务器上的列中的前一个字符(使用 CP-1252),驱动程序会尝试将其转换为 3 字节 UTF-8 编码,但不能将结果拟合到 1 字节缓冲区中。 在另一个方向上,它在客户端和服务器上的不同代码页之间进行转换之前,将 ColumnSize 与 SQLBindParameter 中的 BufferLength 进行比较。 因为 ColumnSize 的值 1 小于 BufferLength 的值(例如)3,因此驱动程序将生成一个错误。 要避免此错误,请确保转换后的数据长度适合指定的缓冲区或列。 ColumnSize 对于 varchar(n) 类型不能大于 8000。
排查连接问题
如果使用 ODBC 驱动程序无法连接到 SQL Server,请使用以下信息确定问题原因。
最常见的连接问题是安装两个 UnixODBC 驱动程序管理器的副本。 搜索 /usr 以查找 libodbc*.so*。 如果看到多个版本的文件,则(可能)安装了多个驱动程序管理器。 你的应用程序可能会使用错误的版本。
通过编辑你的 /etc/odbcinst.ini 文件启用连接日志,使其包含以下部分及这些项:
[ODBC]
Trace = Yes
TraceFile = (path to log file, or /dev/stdout to output directly to the terminal)
如果连接再次失败并且未看到日志文件,则计算机上(可能)存在两个驱动程序管理器的副本。 否则,日志输出应该类似于:
[ODBC][28783][1321576347.077780][SQLDriverConnectW.c][290]
Entry:
Connection = 0x17c858e0
Window Hdl = (nil)
Str In = [DRIVER={ODBC Driver 18 for SQL Server};SERVER={contoso.com};Trusted_Connection={YES};WSID={mydb.contoso.com};AP...][length = 139 (SQL_NTS)]
Str Out = (nil)
Str Out Max = 0
Str Out Ptr = (nil)
Completion = 0
UNICODE Using encoding ASCII 'UTF8' and UNICODE 'UTF16LE'
如果 ASCII 字符编码不是 UTF-8,例如:
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
安装了多个驱动程序管理器,并且应用程序使用了错误的驱动程序管理器,或者驱动程序管理器未正确生成。
某些 macOS 用户在驱动程序版本 17.8 或更低版本中遇到以下错误:
[08001][Microsoft][ODBC Driver 17 for SQL Server]SSL Provider: [OpenSSL library could not be loaded, make sure OpenSSL 1.0 or 1.1 is installed]
[08001][Microsoft][ODBC Driver 17 for SQL Server]Client unable to establish connection (0) (SQLDriverConnect)
安装 OpenSSL 3.0 时,可能会发生此错误。 OpenSSL 通常通过 Homebrew 安装,并包含 openssl、openssl@1.1 和 openssl@3 这些二进制文件。
若要解决此错误,请将 OpenSSL 二进制文件的符号链接更改为 openssl@1.1:
rm -rf $(brew --prefix)/opt/openssl
version=$(ls $(brew --prefix)/Cellar/openssl@1.1 | grep "1.1")
ln -s $(brew --prefix)/Cellar/openssl@1.1/$version $(brew --prefix)/opt/openssl
Related tasks
有关解决这种连接失败的详细信息,请参阅:
- 解决 SQL 连接问题的步骤
- SQL Server 2005 连接问题疑难解答 - 第 I 部分
- 带有连接环形缓冲区的 SQL Server 2008 中的连接疑难解答
- SQL Server 身份验证疑难解答