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

时间:2015-08-05 17:44:03

标签: sql-server character-encoding pyodbc freetds unixodbc

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

如果我的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值不正确。

BTW,我的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()

1 个答案:

答案 0 :(得分:0)

在odbc.ini中使用ClientCharset = WINDOWS-1252替换odbcinst -i -s -f /usr/local/etc/odbc.ini(然后运行Charset = UTF-8)使我的TDS版本7.1适用。

显然在odbc.ini文件中使用#include <stdio.h> #include <stdlib.h> void story(char **string1, int n) { if ( n > 0 ) { printf("a %s who couldn't sleep,\n", *(string1 + n)); printf("so the %s's mother told her a story about\n", *(string1 + n)); story(string1, n - 1); } else { printf("a %s who went to sleep.", *string1); if ( n < 4) { story(string1, n + 1); printf("Then the %s went to sleep.", *(string1 + n)); } } } int main() { char* animals[] = {"bear", "frog", "turtle", "mouse", "child"}; int start = 4; printf("Once upon a time, there was "); story(animals, start); printf("%s", *animals); return 0; } 不能将编码设置为UTF-8(有关详细信息,请参阅http://www.freetds.org/userguide/odbcconnattr.htm)。事实上,ISO_8859-1的默认编码与我以前的设置一起使用。这适用于TDS版本4.2,但不适用于版本7.1,可能是因为自版本7.0(UCS-2)以来TDS传输数据的方式不同。