代码之家  ›  专栏  ›  技术社区  ›  Hubert Schölnast

如何在perl脚本中使用UTF8连接到MySQL?

  •  20
  • Hubert Schölnast  · 技术社区  · 9 年前

    简而言之:

    在Perl脚本中:我如何连接到MySQL,以允许将四字节unicode字符U+1F61C(“”)从Perl脚本传输到应该存储该字符的MySQL表?

    使用 {mysql_enable_utf8 => 1} 不能解决问题。

    具体如下:

    我的问题与问题中描述的完全相同 ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x9C' for column 'comment' at row 1 FACE WITH STUCK-OUT TONGUE AND WINKING EYE )这将生成错误消息

    DBD::mysql::st execute failed: Incorrect string value: '\xF0\x9F\x98\x9C' for column ...
    

    另一个问题中公认的答案是:

    • 运行MySQL 5.5或更高版本。

      mysql> select version();
      +-------------------------+
      | version()               |
      +-------------------------+
      | 5.7.13-0ubuntu0.16.04.2 |
      +-------------------------+
      

      因此,它是5.7,晚于5.5。
      选中的

    • utf8mb4 .
      我检查数据库、表格甚至报告列的字符集:

      mysql> SELECT default_character_set_name FROM information_schema.SCHEMATA 
          -> WHERE schema_name = "myDatabase";
      +----------------------------+
      | default_character_set_name |
      +----------------------------+
      | utf8mb4                    |
      +----------------------------+
      
      mysql> SELECT CCSA.character_set_name FROM information_schema.`TABLES` T,
          ->        information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
          -> WHERE CCSA.collation_name = T.table_collation
          ->   AND T.table_schema = "myDatabase"
          ->   AND T.table_name   = "myTable";
      +--------------------+
      | character_set_name |
      +--------------------+
      | utf8mb4            |
      +--------------------+
      
      mysql>   SELECT character_set_name FROM information_schema.`COLUMNS` 
          -> WHERE table_schema = "myDatabase"
          ->   AND table_name   = "myTable"
          ->   AND column_name  = "myColumn";
      +--------------------+
      | character_set_name |
      +--------------------+
      | utf8mb4            |
      +--------------------+
      

      utf8mb4美元 .
      选中的

    • 在MySQL连接上启用UTF8。
      这似乎就是问题所在。这个 answer to the other question 说:

      SET NAMES utf8 ,或在连接时使用类似启用它的选项。

    我不知道该怎么做 设置名称utf8 连接时的一个选项,类似地启用它 ".
    my $dbh = DBI->connect :

    #!/usr/bin/perl -w
    use strict;
    use warnings;
    use utf8;
    use Encode;
    use DBI;
    binmode STDOUT, ":utf8";
    
    #Here I connect using the parameter mysql_enable_utf8 (create database handle):
    my $dbh = DBI->connect('DBI:mysql:database=myDatabase;host=localhost','aUser','aPassword',{mysql_enable_utf8 => 1});
    
    #Prepare the statement (create statement handle):
    my $sth = $dbh->prepare('INSERT INTO `myTable` (`myColumn`) VALUES(?);');
    
    #This doesn't work: 
    $sth->execute('😜');
    
    #This doesn't work either: 
    $sth->execute(encode_utf8('😜'));
    
    #end processing:
    $dbh->disconnect();
    exit(0);
    

    两次执行都会抛出相同的错误(只有末尾的行号更改):

    DBD::mysql::st execute failed: Incorrect string value: '\xF0\x9F\x98\x9C' for column 'myColumn' at row 1 at myTestScript.pl line 16.
    

    我做错了什么?
    我怎样才能做得更好?

    1 回复  |  直到 9 年前
        1
  •  18
  •   Hubert Schölnast    9 年前

    问题在于 SET NAMES utf8 supports characters up 3 bytes only 所讨论的字符有4个字节:

    MySQL中的utf8字符集具有以下特点:

    不支持补充字符(仅限BMP字符)。

    每个多字节字符最多三个字节。

    真正的utf8是在字段本身中用作字符集的utf8mb4。所以,使用 SET NAMES utf8mb4

    因此,在Perl中,您应该使用 {mysql_enable_utf8mb4 => 1} 而不是 {mysql_enable_utf8 => 1} .

    推荐文章