我是一个新手perl程序员,试图使用DBI将包含带有变音符号和其他非ASCII字符的电子邮件的文本缓冲区写入joomla数据库并遇到问题。
DBD::mysql::st execute failed: Incorrect string value: 'xD6sterl...' for column `lsv5webstage`.`xuxgc_content`.`fulltext` at row 1 at /home/alerts/scripts_linstage/AdvisoryTest.pm line 373.
我对编码的工作原理不够熟悉,无法完全理解问题所在。这是一个带有mariadb-10.3.12和joomla-3.9的fedora29系统。
显然,"\xD6"是"塞巴斯蒂安·斯特伦德"中带有变音符号的O。我读过一些关于 utf8 无法处理 4 个字符的内容,但我不完全理解。
我在网上找到了以下参考资料,其中谈到将编码类型从utf8更改为utf8mb4,但表格似乎都已经在使用该编码:
> SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR
Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
我不确定它是否有帮助,但这是我在perl代码中使用的插入语句:
my $sql = <<EOF;
INSERT INTO xuxgc_content (title, alias, introtext, `fulltext`, state, catid, created, created_by, created_by_alias, modified, modified_by, checked_out, checked_out_time, publish_up, publish_down, images, urls, attribs, version, ordering, metakey, metadesc, metadata, access, hits, language)
VALUES ($title, "$title_alias", $introText, $fullText, $state, $catid, $created, $created_by, $created_by_alias, $modified, $modified_by, $checked_out, $checked_out_time, $publish_up, $publish_down, $images, $urls, $attribs, $version, $ordering, $metakey, $metadesc, $metadata, $access, $hits, $language);
EOF
my $sth = $dbh->prepare($sql);
$sth->execute();
db_disconnect($dbh);
$fullText变量是从包含电子邮件正文的缓冲区填充的。在执行插入之前,我正在通过 quote() 运行它。
$fullText = $dbh->quote($fullText);
我还尝试使用"设置名称utf8mb4;插入到我的表...;",它只是不喜欢这种格式。
以下是用于连接到数据库的完整函数:
sub db_connect () {
my %DB = (
'host' => 'myhost',
'db' => 'mydb',
'user' => 'myuser',
'pass' => 'mypass',
);
return DBI->connect("DBI:mysql:database=$DB{'db'};host=$DB{'host'}", $DB{'user'}, $DB{'pass'}, { mysql_enable_utf8mb4 => 1 });
}
我不记得过去有过这个问题,这个脚本已经使用了很长一段时间。
D6
是CHARACTER SET latin1
(和其他几个)中Ö
的十六进制。
您已经声明您的客户端使用UTF-8
(utf8mb4) 编码,因此它会向您吐口水。
请提供SELECT HEX(col), col ...
以查看D6
是否进入数据库(因此存在插入问题)或其他内容(可能是获取/显示问题)。
此外,您没有引用$fulltext
字符串,因此您可能会收到各种语法错误。
请不要盲目地将字符串放入语句INSERT
,而是在放入字符串时对其进行转义。
这里可能有一些有用的Perl提示:
use utf8;
use open ':std', ':encoding(UTF-8)';
my $dbh = DBI->connect("dbi:mysql:".$dsn, $user, $password, {
PrintError => 0,
RaiseError => 1,
mysql_enable_utf8 => 1, # Switch to UTF-8 for communication and decode.
});
# or {mysql_enable_utf8mb4 => 1} if using utf8mb4
并寻找绑定/引用/转义的技术。