【发布时间】:2011-05-06 13:23:54
【问题描述】:
我正在使用 Perl 和 DBI / DBD::ODBC 从 SQL Server 数据库中检索数据,但在字符编码方面存在一些问题。
数据库的默认排序规则为 SQL_Latin1_General_CP1_CI_AS,因此 varchar 列中的数据以 Microsoft 的 Latin-1 版本编码,也称为 windows-1252。
似乎没有办法在 DBI/DBD::ODBC 中透明地处理这个问题。我得到的数据仍然编码为windows-1252,例如,€“”被编码为字节 0x80、0x93 和 0x94。当我将它们写入 UTF-8 编码的 XML 文件而不先解码它们时,它们被写为 Unicode 字符 0x80、0x93 和 0x94,而不是 0x20AC、0x201C、0x201D,这显然是不正确的。
我目前的解决方法是在每个 fetch 之后的每一列上调用 $val = Encode::decode('windows-1252', $val)。这行得通,但似乎不是正确的方法。
有没有办法告诉DBI 或DBD::ODBC 为我做这个转换?
我正在使用 ActivePerl (5.12.2 Build 1202),DBI (1.616) 和 DBD::ODBC (1.29) 由 ActivePerl 提供并更新为 ppm;在托管数据库的同一台服务器上运行 (SQL Server 2008 R2)。
我的连接字符串是:
dbi:ODBC:Driver={SQL Server Native Client 10.0};Server=localhost;Database=$DB_NAME;Trusted_Connection=yes;
提前致谢。
【问题讨论】:
-
这让我很吃惊。柱子的类型是什么? search.cpan.org/~mjevans/DBD-ODBC-1.29/ODBC.pm#odbc_has_unicode 为您返回什么。 Windows 上的 DBD::ODBC 通常是用 -u 构建的(默认情况下),因此会进行 unicode ODBC 调用并要求 SQL_WCHARs 应该返回 UCS2 编码的数据,对于 Perl,该数据被重新编码为 UTF-8。
-
@bohica:
$dbh->{odbc_has_unicode} == 1。列都是varchar,不是nvarchar。 -
我维护 DBD::ODBC。您能否将其简化为一个检索行的简单脚本,然后使用 DBI_TRACE=15=x.log 运行它并将日志文件发布到某处(在 Windows 上可能设置 DBI_TRACE=15=x.log)。
-
@bohica:会的。同时,即使手动绑定类型为 SQL_WVARCHAR 或 SQL_WCHAR 的列也没有什么不同。看起来 ODBC 驱动程序或 DBD::ODBC 不知道数据在
windows-1252-encoding... -
就我而言,如果要求作为 SQL_WCHAR,它不应该在 windows-1252 中。
标签: sql-server perl odbc dbi