当前位置: 首页 > 面试题库 >

在Linux上使用pyodbc在nvarchar mssql字段中插入unicode或utf-8字符

后星河
2023-03-14
问题内容

我正在使用 Ubuntu 9.04

我已经安装了以下软件包版本:

unixodbc and unixodbc-dev: 2.2.11-16build3
tdsodbc: 0.82-4
libsybdb5: 0.82-4
freetds-common and freetds-dev: 0.82-4

我已经这样配置/etc/unixodbc.ini

[FreeTDS]
Description             = TDS driver (Sybase/MS SQL)
Driver          = /usr/lib/odbc/libtdsodbc.so
Setup           = /usr/lib/odbc/libtdsS.so
CPTimeout               = 
CPReuse         = 
UsageCount              = 2

我已经这样配置/etc/freetds/freetds.conf

[global]
    tds version = 8.0
    client charset = UTF-8

我已经31e2fae4adbf1b2af1726e5668a3414cf46b454f从Pyodbc修订版中获取http://github.com/mkleehammer/pyodbc并使用“
python setup.py install”进行了安装

我有一台装有 Microsoft SQL Server 2000
的Windows机器,安装在本地网络上,并在本地IP地址10.32.42.69上侦听。我有一个名为“ Common”的空数据库。我的用户“
sa”具有完全特权的密码“ secret”。

我正在使用以下python代码设置连接:

import pyodbc
odbcstring = "SERVER=10.32.42.69;UID=sa;PWD=secret;DATABASE=Common;DRIVER=FreeTDS"
con = pyodbc.connect(s)
cur = con.cursor()
cur.execute('''
CREATE TABLE testing (
    id INTEGER NOT NULL IDENTITY(1,1), 
    name NVARCHAR(200) NULL, 
    PRIMARY KEY (id)
)
    ''')
con.commit()

一切 WORKS 了这一点。我在服务器上使用了SQLServer的企业管理器,并且有新表。现在,我想在表上插入一些数据。

cur = con.cursor()
cur.execute('INSERT INTO testing (name) VALUES (?)', (u'something',))

失败了!这是我得到的错误:

pyodbc.Error: ('HY004', '[HY004] [FreeTDS][SQL Server]Invalid data type 
(0) (SQLBindParameter)'

由于我的客户端配置为使用UTF-8,所以我认为我可以通过将数据编码为UTF-8来解决。那行得通,但随后我得到了奇怪的数据:

cur = con.cursor()
cur.execute('DELETE FROM testing')
cur.execute('INSERT INTO testing (name) VALUES (?)', (u'somé string'.encode('utf-8'),))
con.commit()
# fetching data back
cur = con.cursor()
cur.execute('SELECT name FROM testing')
data = cur.fetchone()
print type(data[0]), data[0]

这没有错误,但是返回的数据与发送的数据不同!我得到:

<type 'unicode'> somé string

也就是说,pyodbc不会直接接受unicode对象,但是会将unicode对象返回给我!和编码混在一起!

现在问题是:

我想要代码在NVARCHAR和/或NTEXT字段中插入unicode数据。当我回查询时,我想要回插入的相同数据。

可以通过不同地配置系统,或使用包装器功能在插入或检索时能够将数据正确地从Unicode转换为/从Unicode转换为数据。

要求不高,是吗?


问题答案:

我记得使用odbc驱动程序时会遇到这种愚蠢的问题,即使那是Java + oracle的组合。

核心是,odbc驱动程序在将查询字符串发送到数据库时显然会对其进行编码。即使该字段是Unicode,并且即使您提供Unicode,在某些情况下也似乎无关紧要。

您需要确保驱动程序发送的内容与数据库(不仅是服务器,而且还有数据库)具有相同的编码。否则,您当然会得到一些时髦的字符,因为在编码/解码时,客户端或服务器都会混淆。您是否知道服务器将其用作解码数据的默认字符集(如MS所说的代码点)?

整理与这个问题无关:)

例如,请参见该MS页面。对于Unicode字段,排序规则仅用于定义列中的排序顺序, 而不
用于指定数据的存储方式。

如果您将数据存储为Unicode,则有一种独特的方式来表示它,这就是Unicode的目的:无需定义与要使用的所有语言兼容的字符集:)

这里的问题是“当我将数据提供给 Unicode服务器时会发生什么?”。例如:

  • 当我向服务器发送UTF-8字符串时,它如何理解?
  • 当我向服务器发送UTF-16字符串时,它如何理解?
  • 当我向服务器发送Latin1字符串时,它如何理解?

从服务器的角度来看,所有这三个字符串只是字节流。服务器无法猜测您对其进行编码的编码。这意味着,如果您的odbc客户端最终向服务器发送 字节字符串
(编码字符串)而不是发送 unicode 数据, 则会
遇到麻烦:如果这样做,服务器将使用预定义的编码(这是我的问题:服务器将使用?(因为不能猜测,它必须是一个参数值),并且如果字符串是使用其他编码
dzing 编码的, 数据将被破坏。 __

它与Python中的操作完全相似:

uni = u'Hey my name is André'
in_utf8 = uni.encode('utf-8')
# send the utf-8 data to server
# send(in_utf8)

# on server side
# server receives it. But server is Japanese.
# So the server treats the data with the National charset, shift-jis:
some_string = in_utf8 # some_string = receive()    
decoded = some_string.decode('sjis')

就试一试吧。很有趣。解码后的字符串应该是“嘿,我的名字是安德烈”,但是应该是“嘿,我的名字是安德烈”。é被日文replaced取代

因此,我的建议是:您需要确保pyodbc能够直接将数据作为Unicode发送。如果pyodbc无法做到这一点,您将得到意想不到的结果。

我以客户端到服务器的方式描述了问题。但是,当从服务器向客户端进行通信时,可能会出现相同类型的问题。如果客户端无法理解Unicode数据,您可能会遇到麻烦。

FreeTDS为您处理Unicode。

实际上,FreeTDS会为您处理事务,并将所有数据转换为UCS2
unicode。(来源)。

  • 服务器<-> FreeTDS:UCS2数据
  • FreeTDS <-> pyodbc:编码的字符串,以UTF-8编码(来自/etc/freetds/freetds.conf

因此,如果您将UTF-8数据传递给pyodbc,我希望您的应用程序能够正常工作。实际上,正如此django-
pyodbc票证所指出的那样,django-pyodbc在UTF-8中与pyodbc进行通信,所以应该没事。

FreeTDS 0.82

但是,cramm0表示FreeTDS
0.82并非完全没有错误,并且0.82和可以在此处找到的官方补丁0.82版本之间存在显着差异。您可能应该尝试使用修补的FreeTDS

编辑删除了与FreeTDS无关的旧数据,但仅与Easysoft商业odbc驱动程序有关。 抱歉。



 类似资料:
  • null DB cfg获取 DB2数据库区域设置配置 语句正确执行,并且数据库中的行正确显示: null null 我认为这可能是一些编码问题在客户端,或服务器由于配置,文件或sql编码。 更新: 我还尝试用SQL加载一个UTF-8文件。文件正确加载,使用UTF-8字符调试SQL也正确传递给语句,但结果是相同的。 但在数据库中,测试显示为: 十六进制表示: 我认为DB2 Java客户机可能使用所有

  • 我需要添加用户名从Facebook到数据库,这些名称有UTF-8字符,如 (ą,č,ę,ė,į,š,ų,ū).当我把它添加到数据库中,例如字母看起来像

  • 3. 在Linux C编程中使用Unicode和UTF-8 目前各种Linux发行版都支持UTF-8编码,当前系统的语言和字符编码设置保存在一些环境变量中,可以通过locale命令查看: $ locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE

  • 我需要在html页面上插入一个欧米茄(欧米茄)。我使用它的HTML转义代码来实现这一点,因此我可以编写并获得?。当我将它放入HTML元素中时,这一切都很好;但是,当我尝试将其放入我的JS中时,例如时,它将代码解析为JS,整个过程无法运行。有人知道怎么做吗?

  • 问题内容: 我目前正在从事一个项目,我不使用常规的MySQL查询,而是继续学习如何使用PDO。 我有一个称为参赛者的表,数据库,表和所有列均位于utf-8中。我的参赛者表中有10个条目,而它们的“名称”列中包含诸如åäö之类的字符。 现在,当我从数据库中获取一个条目并使用var_dump的名称时,我得到了一个很好的结果,即一个包含所有特殊字符的字符串。但是我需要做的是按字符分割字符串,将它们放入数

  • 问题内容: 如何在Swift中将字符串转换为Unicode(UTF-8)字符串? 在Objective中,我可以这样写: 如何在Swift中做类似的事情? 问题答案: 使用此代码, 希望对您有所帮助