在纯UTF-8环境中使用CONCAT()的原因是什么原因MySQL仍然将连接字符串(当表达式中的某些col为例如int或date)视为其他字符集(可能是Latin-1)?
从客户端(\s
)看到的MySQL环境:
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
测试数据集:
CREATE TABLE `utf8_test` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(50) collate utf8_estonian_ci default NULL,
`year` smallint(4) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_estonian_ci;
INSERT INTO utf8_test VALUES (1, 'Õäöüšž', 2011);
此查询很好:
SELECT id, title FROM utf8_test;
这个关闭utf-8标志(已经在MySQL,AFIU):
SELECT CONCAT(id, title) FROM utf8_test;
从mysql-client看来一切都很好,因为它被设置为将字符显示为UTF-8,但是当通过perl DBI运行时,所有内部具有CONCAT()的查询结果都没有设置utf-8标志。示例代码:
#!/usr/bin/perl
use strict;
use utf8::all;
use Encode qw(is_utf8);
my $dbh = your_db_connect_routine('test');
my $str = $dbh->selectrow_array('SELECT CONCAT(id, title) FROM utf8_test');
print "CONCAT: False\n" unless ( is_utf8($str) );
my $str = $dbh->selectrow_array('SELECT title FROM utf8_test');
print "NO CONCAT: False\n" unless ( is_utf8($str) );
我知道至少有两种解决方法
SELECT CONCAT( CAST(id AS CHAR CHARACTER SET utf8), title) FROM utf8_test
$str = Encode::_utf8_on($str)
(被视为不良做法?)但我在问:为什么它在MySQL中呢?我应该将其视为错误还是功能?
答案 0 :(得分:20)
这是MySQL中一个众所周知的错误。它已在MySQL 5.5中修复
请参阅:http://bugs.mysql.com/bug.php?id=12030
问题源于将整数与varchar连接。
解决方法是首先将id(整数)转换为char,然后连接, 即:
SELECT CONCAT(cast(id as char), title) FROM utf8_test
答案 1 :(得分:0)
它可能是DBD :: mysql问题/特殊性。尝试在数据库句柄中启用utf8,如DBD::mysql
mysql_enable_utf8
({{1}}部分)所述。
这个旧的(Perl 5.8次)POD也可以提供帮助。