我有以下用于Sqlite数据库的简单Perl包装器:
#! /usr/bin/perl
use strict;
use warnings;
use DBI;
use Data::Dumper;
my $sql = shift;
my $dbh = DBI->connect(
"dbi:SQLite:dbname=data.sqlite3",
"", # no user
"", # no pw
{
RaiseError => 1,
sqlite_unicode => 1
},
) || die $DBI::errstr;
my $sth = $dbh->prepare($sql);
$sth->execute();
print Dumper ($sth->fetchall_arrayref({}));
$sth->finish();
$dbh->disconnect();
尽管我已经设置了sqlite_unicode
标志(如文档中所述),但我无法执行包含Unicode字符的查询:
$ ./sqlite.pl "select * from person where lastname = 'Schütte'"
$VAR1 = [];
当我掩盖'ü'时,似乎不确定,尽管我不确定,是\x{fc}
指Latin 1FC
还是UnicodeU+00FC
。
$ ./sqlite.pl "select * from person where lastname like 'Sch%tte'"
$VAR1 = [
{
'id' => 8,
'firstname' => undef,
'lastname' => "Sch\x{fc}tte"
}
];
当我使用Sqlite命令行工具执行相同操作时,它可以正常工作:
$ sqlite3 data.sqlite3 "select * from person where lastname = 'Schütte'"
8||Schütte
我是否忘记了任何要告诉DBI层支持Unicode字符的内容?
我的本地编码是UTF-8:
$ locale
LANG=de_DE.utf8
LANGUAGE=
LC_CTYPE="de_DE.utf8"
LC_NUMERIC="de_DE.utf8"
LC_TIME="de_DE.utf8"
LC_COLLATE="de_DE.utf8"
LC_MONETARY="de_DE.utf8"
LC_MESSAGES="de_DE.utf8"
LC_PAPER="de_DE.utf8"
LC_NAME="de_DE.utf8"
LC_ADDRESS="de_DE.utf8"
LC_TELEPHONE="de_DE.utf8"
LC_MEASUREMENT="de_DE.utf8"
LC_IDENTIFICATION="de_DE.utf8"
LC_ALL=
您需要问自己的第一个问题是:
应该对查询进行编码(如果可以的话,采用哪种编码),还是应该对查询进行解码(即Unicode代码点)?
这应该基于sqlite_unicode
,但不是。那只会影响返回的字符串。我怀疑DBD :: SQLite与大多数/所有DBD一样,都遭受Unicode错误的困扰,这意味着问题的答案是基于字符串存储方式的内部细节。
在UTF-8系统中,它通常“可以正常工作”,我很惊讶它不在这里。请试试
use Encode qw( decode_utf8 );
my $sql = decode_utf8(shift);
如果这样做不起作用,请提供以下输出(在将查询移出之前@ARGV
):
use Devel::Peek qw( Dump );
Dump($ARGV[0]);
当我掩盖'ü'时,似乎不确定,尽管我不确定,是否
\x{fc}
表示Latin 1 FC或UnicodeU+00FC
。
这个问题没有任何意义。在iso-latin-1和Unicode中,FC
都是“ü”。我相信你实际上是在问
返回的字符串是使用iso-latin-1编码的还是解码的字符串(即Unicode代码点)?
使用sqlite_unicode
,它们就是后者。您需要对输出进行编码。您可以按照以下方式进行操作:
use open ':std', ':encoding(UTF-8)';
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句