执行失败:不正确的字符串值:'\xD6sterl…'与mariadb和perl DBD
我是一个新手perl程序员,试图使用DBI将包含umlauts和其他非ASCII字符的电子邮件的文本缓冲区写入joomla数据库,但遇到了问题执行失败:不正确的字符串值:'\xD6sterl…'与mariadb和perl DBD,perl,utf-8,mariadb,utf8mb4,dbd,Perl,Utf 8,Mariadb,Utf8mb4,Dbd,我是一个新手perl程序员,试图使用DBI将包含umlauts和其他非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.
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,在Sebastian中带有一个umlaut�斯特伦德。我读到一些关于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代码中使用的insert语句:
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);
我还尝试使用集合名utf8mb4;插入Mytable。。。;它只是不喜欢这种格式
以下是用于连接数据库的完整函数:
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是字符集latin1和其他几个字符集中的十六进制表示Ö
您已经声明您的客户机使用UTF-8 utf8mb4编码,因此它对您进行了攻击
请提供选择的HEXcol、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
并寻找绑定/引用/转义的技术。我不熟悉Perl,但如果Perl支持16位转义,则应该是\u00D6,或者对于组成UTF-8编码的两个字节,应该是\xC3\x96。您使用的是DBD::MariaDB吗?$fullText变量从何处填充?请注意,虽然默认情况下连接和数据库可能使用utf8mb4,但您还应该检查表定义,因为列本身具有最终用于存储的字符集的设置。顺便说一下,您可以使用\N{U+00D6}来表示字符串中的字符。不是DBI驱动程序和MariaDB的UTF-8编码。请确保mysql连接设置包含此标志集mysql\u enable\u utf8或更好的mysql\u enable\u utf8mb4。是否展开选择HEXcol,col?另外,我还以为我是在用backticks转义$fulltext变量?我还相信我正在使用mysql\u enable\u utf8mb4,尽管我不确定。我将更新帖子以包含完整的DBI->connect函数。@AlexRegan-Backtics用于列名。内容需要像转义引号这样的东西,这样你就可以创建一个带引号的字符串!
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