执行失败:不正确的字符串值:'\xD6sterl...',带有mariadb和Perl DBD

n1bvdmb6  于 2022-11-08  发布在  Perl
关注(0)|答案(1)|浏览(134)

我是一个Perl程序员新手,尝试使用DBI向joomla数据库写入一个文本缓冲区,其中包含一封带有变音和其他非ASCII字符的电子邮件,但遇到了问题。

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.

我对编码的工作原理不够熟悉,无法完全理解问题出在哪里。这是一个fedora 29系统,里面有mariadb-10.3.12和joomla-3.9。
显然,“\xD6”是“塞巴斯蒂安'sterlund”中带有元音变音的O。我读到一些关于utf8无法处理4字符的内容,但我不完全理解。
我在网上找到了下面的参考资料,它讨论了将编码类型从utf8更改为utf8 mb 4,但是所有的表似乎都已经使用了该编码:

> 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);

$fullText变量是从包含电子邮件正文的缓冲区中填充的,我在执行INSERT之前通过quote()运行它。

$fullText       = $dbh->quote($fullText);

我还尝试使用“设置名称utf8 mb 4;插入到我的表中...;“它只是不喜欢的格式。
下面是用于连接到数据库的完整函数:

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 });
 }

我不记得过去有过这个问题,这个脚本已经使用了很长一段时间。

j8yoct9x

j8yoct9x1#

D6CHARACTER SET latin1(以及其他几个)中Ö的十六进制。
您已经声明您的客户机使用UTF-8(utf8 mb 4)编码,因此它会对您进行攻击。
请提供SELECT HEX(col), col ...以查看D6是否进入数据库(因此出现 insert 问题)或其他问题(可能是提取/显示问题)。
此外,您还没有用引号将$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

并寻找绑定/引用/转义的技术。

相关问题