【发布时间】:2019-02-09 14:56:01
【问题描述】:
我们有一个用 perl 编写的软件,它可以从 mysql 数据库中检索数据。 为此,我们使用 DBD::mysql 接口
我们可以正确检索所有数据,db 是 UTF8MB4,perl 应用程序使用 UTF-8。
获取sql结果的代码为:
use utf8;
use encoding 'utf8';
...
my $dsn = "DBI:mysql:database=mydatabase;mysql_enable_utf8=1";
my $dbh = DBI->connect($dsn, $userid, $password, { mysql_enable_utf8 => 1 } ) or die $DBI::errstr;
...
my $sth = $dbh->prepare("SELECT addressid,
company, firstname, lastname,
address, zip, city, country,
phone, mobile, home,
speeddial_phone, speeddial_mobile, speeddial_home,
fax, email
FROM address
WHERE (firstname like ? or lastname like ? or company like ?)
LIMIT $sizeLimit
");
$sth->execute( $searchExpression, $searchExpression, $searchExpression) or die $DBI::errstr;
只要 $searchExpression 包含普通字符,它就可以正常工作。 但是一旦我们使用非 ASCII 的特殊字符进行查询,例如 é ö ä ü 等,我们就不会得到空结果集。
根据这篇文章,这是由于版本 4.041_01 之前的 dbd::mysql 驱动程序中的一个错误
http://blogs.perl.org/users/mike_b/2016/12/dbdmysql-all-your-utf-8-bugs-are-belong-to-us.html
我已经测试了不同的东西,但无济于事。
我确实在 mysql 服务器中打开了请求日志记录,在那里我看到带有特殊字符的参数以错误的编码方式进入。
这里是mysql日志的输出到文件:
Time Id Command Argument
180905 9:17:06 403 Connect inno-ldap-db@localhost on phonebook_innovaphone
403 Query SELECT addressid,
company, firstname, lastname,
address, zip, city, country,
phone, mobile, home,
speeddial_phone, speeddial_mobile, speeddial_home,
fax, email
FROM address
WHERE companyid='1' and (firstname like 'andré%' or lastname like 'andré%' or company like 'andré%' )
LIMIT 25
403 Quit
由于我们目前无法升级系统(它是 debian 7,其中仅包含 4.021-1+deb7u3 等较旧的软件包),因此我需要解决该问题。
要么是一些魔法来预编码/解码参数,要么 odbc 驱动程序可能不会遇到这个错误?
【问题讨论】:
-
“$dsn”是否包含“mysql_enable_utf8=1”?我不确定你指向的错误是你的问题,因为那是关于 DBD::mysql 没有将'latin1'变量转换为'utf8';但是 $searchExpression 应该已经是 utf-8 编码,因为 'use utf8;'在顶部。另外,您确定正确检索了 utf-8 数据吗?尝试使用不仅包含西方/拉丁1字符(ä、ü等)而且还包含ą、ă、ш、я的字段。
-
我确实在连接中指定了 mysql_enable_utf8=1,但我现在也将它添加到了 $dns,没有任何区别。我现在还添加了一行上面提到的字符,它们被正确检索。好像只有perl->mysql这个方向有问题。 (我不从 perl 插入/更新数据,只查询它或作为查询过滤器参数)
-
'warn "utf8 ", utf8::is_utf8($searchExpression) 是什么意思? “开\n”:“关\n”;'就在 $sth->execute 行之前?
-
@mosvy 它显示:utf8 on
-
我刚刚尝试过一个较旧的 debian wheezy (libdbd-mysql-perl_4.021-1+deb7u3, libdbi-perl_1.622-1+deb7u1) 但无法重现。对不起。我能想到的唯一一件事是该错误在其他地方,并且 $searchExpression 在传递给 $sth->execute; 之前已经被双重编码为 utf8;但你可能已经检查过了。
标签: mysql perl utf-8 dbi utf8mb4