[英]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
。
✅已檢查
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.