簡體   English   中英

如何在 perl 腳本中使用 UTF8 連接到 MySQL?

[英]How to connect to MySQL using UTF8 within a perl script?

簡而言之:

在 Perl 腳本中:如何以允許將四字節 unicode 字符 U+1F61C ("") 從 perl 腳本傳輸到應存儲此字符的 MySQL 表的方式連接到 MySQL?

使用{mysql_enable_utf8 => 1}不能解決問題。

詳細:

我有與問題ERROR 1366 (HY000) 中描述的完全相同的問題:不正確的字符串值:'\xF0\x9F\x98\x9C' for column 'comment' at row 1 and even with the same Unicode character ( = U+ 1F61C = 吐舌頭和眨眼的臉),它會產生錯誤消息

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

但是我不用PHP,我用的是Perl。

另一個問題中接受的答案是:

  • 運行 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。
    這似乎是問題所在。 另一個問題的答案是

    SET NAMES utf8 ,或在連接時使用類似啟用它的選項。

我不知道如何在 perl 腳本中SET NAMES 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.

我究竟做錯了什么?
我怎樣才能做得更好?

問題出在SET NAMES utf8命令上。 在MySQL中,utf8字符集不是真正的utf8,它僅支持3個字節的字符,並且所討論的字符有4個字節:

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

•不支持增補字符(僅限BMP字符)。

•每個多字節字符最多三個字節。

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

所以從Perl你應該使用{mysql_enable_utf8mb4 => 1}而不是{mysql_enable_utf8 => 1}

我嘗試了很多次,以多種不同的方式,使 cgi 腳本能夠正常工作以從 STDIN 讀取輸入,讀取 html 文件,將其打印到 STDOUT 並正確搜索 mysql 上的輸入文本。 mysql 連接后的屬性 mysql_enable_utf8mb4 和“SET NAMES utf8mb4”與“meta charset='UTF-8'”一起正常工作。

#!/usr/bin/perl
print "Content-type: text/html; charset=UTF-8\n\n";

#use utf8;
#use open ':utf8';
#binmode STDOUT, ":utf8";
#binmode STDIN , ":utf8";
#use encoding 'utf8';

our $dbh = DBI->connect("DBI:mysql:database=$database;host=$servername;port=$port",$username,$password, {PrintWarn => 0, PrintError => 0, mysql_enable_utf8mb4 => 1}) || die;
$dbh->do("SET NAMES utf8mb4");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM