【发布时间】:2011-09-17 20:05:03
【问题描述】:
在纯 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) );
我知道至少有两种解决方法
- 使用 CAST() 查询
SELECT CONCAT( CAST(id AS CHAR CHARACTER SET utf8), title) FROM utf8_test - 使用
$str = Encode::_utf8_on($str)(被认为是不好的做法?)
但我在问:为什么它在 MySQL 中?我应该将其视为错误还是功能?
【问题讨论】:
-
除了 Perl DBI 之外的其他客户端会发生什么?例如,MySQL GUI 工具或其他语言?您还尝试过替代驱动程序,例如
DBD::Wire10 -
@Dan:
DBD::Wire10有同样的行为。但在 Python 中可以正常工作。 DBI 中还有问题吗?