8错误

ghhkc1vu  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(430)

我们有一个用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驱动程序可能不会遇到这个错误?

lnxxn5zx

lnxxn5zx1#

结果是,字符串(通过net::ldap::server接收)已经采用了某种utf8编码,然后mysql驱动程序再次对其进行了编码。
通过添加此代码解决了问题

use Encode qw( decode );
my $decoded = eval { decode('UTF-8', $encoded, Encode::FB_CROAK) }

摘自本文的代码:在perl中编码检测的正确方法
谢谢你给mosvy关于双重编码的提示

相关问题