问题描述:
从php界面insert数据到mysql,只能输入偶数个汉字不能输入奇数个汉字,输入奇数个汉字后报“Data too long for column ”错误,并没有更改数据库数据。到数据库查看,发现汉字都是乱码。但是php界面显示汉字正常(当然显示的都是偶数个汉字,奇数个汉字都没有写入数据库)。
解决思路:
1.更改my.ini文件,把sql-mode=”STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”改成sql-mode=”NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”(就是去掉STRICT_TRANS_TABLES)。重启mysql。
这样做的结果是,不会报“Data too long for column ”,于是奇数个汉字就能存入数据库。但是php界面显示奇数个汉字的地方出错,根据错误可以发现是汉字解析时把部分代码误认一并解析了,所以php界面显示不正常。这说明是汉字转换的错误(对于汉字UTF8则需要3 Bytes而ANSI/Unicode/UCS2编码都只用2 Bytes,此时输入汉字的个数为2个时数据库里的乱码是3个,说明1个乱码是2 Bytes,解析到界面时没有缺失所以可以正常显示;而输入汉字的个数为1个时数据库里的乱码是1个,说明变乱码时失去了1 Byte,解析到界面时有缺失所以不能正常显示)。
2.写一个关于insert或update奇数个汉字的test.sql文件存成utf8放在C盘。在mysql里执行source c:/test.sql;
结果发现仍然是乱码。所以确定mysql的character设置有问题。
3.学习修改mysql的character设置。
MySQL 4.1以上版本的字符集支持(Character Set Support)有两个方面:字符集(Character set)和排序方式(Collation)。对于字符集的支持细化到四个层次: 服务器(server),数据库(database),数据表(table)和连接(connection)。我们最终的目标是使得这四个层次转化会支持中文的编码。
命令一:mysql> SHOW VARIABLES LIKE ''character_set_%'';
查看系统的字符集,结果如下
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | gbk |
| character_set_system | utf8 |
| character_sets_dir | C:/Program Files/MySQL/MySQL Server 5.1/share/charsets/ |
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | gbk |
| character_set_system | utf8 |
| character_sets_dir | C:/Program Files/MySQL/MySQL Server 5.1/share/charsets/ |
+--------------------------+---------------------------------------------------------+
命令二:mysql> SHOW VARIABLES LIKE ''collation_%'';
查看系统的排序方式,结果如下
查看系统的排序方式,结果如下
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | gbk_chinese_ci |
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | gbk_chinese_ci |
+----------------------+-----------------+
命令三:SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
另外一种方法是:SET NAMES “UTF8”;
总之就是用这个方法改变字符集设置,是设成utf8还是gbk根据自己的实际情况定。我经过多次尝试,找到了执行source c:/test.sql;不出乱码的设置。
但是,从php界面输入仍有乱码。这时考虑是不是php那边设置不对。
4.在mysql_connect后面加一句SET NAMES UTF8 或是GBK,根据数据库的设定而定。代码如下
$mysql_mylink = mysql_connect($mysql_host, $mysql_user, $mysql_pass);
mysql_query("SET NAMES 'UTF8'");
mysql_query("SET NAMES 'UTF8'");
到此问题解决了。但是我还是不明白,我在数据库端已经设置了相关参数,为什么web端在连接数据库执行命令前还要执行一次SET NAMES “UTF8”;?