我们有一个用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的特殊字符进行查询时é ö ä ü 类似的,我们不会得到一个空的结果集。
根据这篇文章,这是由于dbd::mysql驱动程序在版本4.041\u01之前的一个bug造成的
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
由于我们目前无法升级系统(它是debian7,它只包括像4.021-1+deb7u3这样的旧软件包),我需要实现一个解决问题的方法。
或者一些魔术来预编码/解码参数,或者odbc驱动程序可能不会遇到这个错误?
1条答案
按热度按时间lnxxn5zx1#
结果是,字符串(通过net::ldap::server接收)已经采用了某种utf8编码,然后mysql驱动程序再次对其进行了编码。
通过添加此代码解决了问题
摘自本文的代码:在perl中编码检测的正确方法
谢谢你给mosvy关于双重编码的提示