Linux 和 macOS 上的 ODBC 驱动程序的已知问题
本文包含 Linux 和 macOS 上的 Microsoft ODBC Driver for SQL Server 13、13.1、17 和 18 的已知问题列表。 它还包含用于排查连接问题的步骤。
已知问题
其他问题将在 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)时,驱动程序管理器尝试此转换。 当调用 SQLWCHAR 版本的 ODBC API(例如,SQLDriverConnectW)时,驱动程序管理器不会尝试此转换。
SQLBindParameter 的 ColumnSize 参数指的是 SQL 类型的字符数,而 BufferLength 是应用程序缓冲区中的字节数 。 但是,如果 SQL 数据类型为
varchar(n)
或char(n)
,且应用程序将参数绑定为 C 类型的 SQL_C_CHAR 以及 SQL 类型的 SQL_CHAR 或 SQL_VARCHAR,并且客户端的字符编码为 UTF-8,可能会从驱动程序收到“字符串数据,右截断”错误,即使 ColumnSize 的值与服务器上的数据类型大小保持一致。 出现此错误是因为字符编码之间的转换可能会更改数据的长度。 例如,右单引号字符 (U+2019) 以 CP-1252 编码为单字节 0x92,但以 UTF-8 则编码为 3 个字节序列 - 0xe2 0x80 0x99。
例如,如果采用 UTF-8 编码,并且为 out 参数的 SQLBindParameter 中的 BufferLength 和 ColumnSize 均指定 1,然后尝试检索存储在服务器上的 char(1)
列中的前一个字符(使用 CP-1252),则驱动程序会尝试将其转换为 3 个字节的 UTF-8 编码,但无法使结果适合 1 个字节的缓冲区 。 如果条件相反,它会比较 SQLBindParameter 中的 ColumnSize 和 BufferLength,然后在客户端和服务器上的不同代码页之间进行转换 。 因为 ColumnSize 的值 1 小于 BufferLength 的值(例如)3,因此驱动程序将生成一个错误。 要避免此错误,请确保转换后的数据长度适合指定的缓冲区或列。 请注意,对于 varchar(n)
类型,ColumnSize 不能大于 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 或更低版本中遇到以下错误:
(此错误在驱动程序版本 17.9 及以上版本中已解决)
[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 通常通过 Brew 安装,它包含 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
有关解决这种连接失败的详细信息,请参阅:
- 解决 SQL 连接问题的步骤
- SQL Server 2005 连接问题疑难解答 - 第 I 部分
- 带有连接环形缓冲区的 SQL Server 2008 中的连接疑难解答
- SQL Server 身份验证疑难解答
后续步骤
有关 ODBC 驱动程序安装说明,请参阅以下文章: