http://hi.baidu.com/cnkarl/item/e18214e8ba7ce3c6bbf37ddd
——————————————————————————————————————————————————————————————————————————————————
解决mysql的utf8编码中生僻字写入时"Incorrect string value"错误
其他中文显示非常正常,但是在写入“姮”、"旻"等比较生僻的人名时报告错误:
Incorrect string value "..." for column ...
看似是gb2312字符集不全面的问题,换用gbk的话应该就没什么问题了,
但是疑问在这里:数据和程序以及前台都使用的是utf8字符集,
难道utf8字符集支持的中文还没有gbk全面吗,理论来说是不可能的,utf8编码直接映射unicode,字符集应该是最全面的。
数据库设置是正确的:
MYSQL配置文件my.ini 中 default-character-set=utf8
建立的数据库的charset也是utf8
甚至要写入的表"tb_test"的charset也是utf8, collection是utf8_general_ci
php中连接数据库时也明文指定了字符集:
$db = mysql_connect($dbhost, $dbuser, $dbpwd);
mysql_query("SET NAMES utf8", $db);
mysql_select_db($dbname, $db);
但是为什么会出现这种错误呢?反复检查之后发现,原来tb_test中,存储人名的`name`列的编码方式居然是gb2312。(系统是从旧系统集成和升级过来的,而数据表也来自旧数据表,以前的系统是gb2312编码的,升级过程中程序员只修改到表的字符集,而没有修改列的字符集)
解决方法:
将
表结构和数据dump成文本脚本,使用支持utf8编码的编辑器打开脚本(推荐EditPlus),去除指定列的字符集gb2312的修饰符(因为表的字
符集已经是utf8,所以去除列的字符集修饰后,列的字符集会自动继承表的设置,成为utf8)。如sql文件中其中一行:
`name` varchar(32) character set gb2312 NOT NULL,
删除其中字符集部分:
`name` varchar(32) NOT NULL,
如果存储的数据不是utf8的编码,还要使用EditPlus的 文档/文档编码方式 功能将数据转换为utf8编码。
修改转换完毕后保存脚本,备份旧表,执行这个脚本文件,列的字符集设定就统一为utf8了。
心得:
可以看出,MYSQL(本文所说的mysql版本为5.067)的字符集设定分为4个层次:
1.服务器默认设置 my.ini 中的 default-character-set=utf8
2.建立数据库时的字符集指定:CREATE DATABASE CHARACTER SET utf8;
3.建立表时的字符集指定:CREATE TABLE `db_database`.`tb_test` (....) DEFAULT CHARSET=utf8;
4.建立列时,指定的字符集:ADD COLUMN `name` VARCHAR(45) CHARACTER SET utf8
其中某一级如果不指定字符集,则会自动继承上一级的字符集设定。
所以为了方便日后的集成、升级和移植等工作,如果无特殊需求,建立数据库的时候将字符集指定到“数据库”或“表”级别即可,无需给每一列都显式地指定字符集。
傲轩游戏网