[英]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.