使用 tds 版本 7.1 与 4.2 时,pyodbc 查询 returns 不同的 varchar 值

pyodbc query returns different varchar values when using tds version 7.1 versus 4.2

我使用 freetds(v0.95.19)/unixODBC(2.3.1)/pyodbc(3.0.7) 从 ubuntu 12.04 访问 MS SQL 服务器 2012。我想检索包含非 ASCII 字符的 varchar(不是 nvarchar)的值。

如果我的 odbc.ini 文件是这样的

[mydb]
Driver = FreeTDS
Description = mydb description
Trace = No
Server = mydb.xxxxx.xxx
Database = XXX
Port = 1433
Charset = UTF-8
TDS_Version = 4.2

则检索到的值为'\x841\x84\xc1\xcd\xc5;\x9b*\xf5\xb5\xc1}|\xcbX',即期望值。

但是,如果我只是将 TDS_Version 更改为 7.1,检索到的值将变为 '?1?\xc1\xcd\xc5;?*\xf5\xb5\xc1}|\xcb',它会替换字符 ' \x84' 和 '\x9b' 与 '?'并且在字符串末尾缺少 'X'。

我已经尝试了所有我能想到的方法(包括将 freetds、unixODBC 和 pyodbc 更新到最新的稳定版本),但到目前为止似乎没有任何帮助。使用 TDS 4.2 版还有一些其他问题,所以我真的希望让 7.1 版工作,但我无法弄清楚为什么检索到的 varchar 值不正确。

顺便说一句,我的 freetds.conf 文件包含以下内容(此文件中的 tds 版本是否为 7.1 似乎并不影响我使用 pyodbc 获得的结果)。

[global]
tds version=4.2

[mydb]
host = mydb.xxxxx.xxx
tds version = 7.1
port = 1433
client charset = UTF-8

在python (2.7.3) 我做

import pyodbc
conn=pyodbc.connect('DSN=mydb;DATABASE=XXX;UID=XXX;PWD=XXX')
cursor=conn.cursor()
cursor.execute("select myVarcharColumn from my.table where id=XXX").fetchone()

Charset = UTF-8 替换为 odbc.ini 中的 ClientCharset = WINDOWS-1252(然后是 运行 odbcinst -i -s -f /usr/local/etc/odbc.ini)使我的 TDS 7.1 版工作正常。

显然 odbc.ini 文件中的 Charset = UTF-8 无法将编码设置为 UTF-8(有关详细信息,请参阅 http://www.freetds.org/userguide/odbcconnattr.htm)。事实上,ISO_8859-1 的默认编码用于我之前的设置。这适用于 TDS 4.2 版,但不适用于 7.1 版,可能是因为 TDS 传输数据的方式与 7.0 (UCS-2) 版不同。