Warning: #1366 Incorrect string value 内容被截取或不能正常操作数据库

提示:#1366 - Incorrect string value: '/xE2/x80/x94200...' for column

发现自己写进去的内容没有问题,但是如果复制其他网页的内容偶尔会出现问题。搜索下这个问题,找到了 答案,共享出来希望能够帮助遇到这个问题的朋友!!!

 

言归正传:

mysql4.1开始分字符集了,在保存数据时候会检查和转换数据编码。最近有个客户反应发表文章,有部分保存后内容被截断了,只保存了一部分,我 一测试发现是编码问题引起的。

这客户网页和数据库用的都是是big5编码,默认程序连上数据库后会发一句:
"SET character_set_connection=big5, character_set_results=big5, character_set_client=binary"

简单解释下:character_set_client 是客户端编码,character_set_connection 是连接编码,character_set_results 是查询结果返回编码
另外要注意的是,mysql表和字段本身有编码属性,实际保存时候mysql会检查每个字段编码并尝试转换。
所以保存数据的转换流程是,character_set_client 编码转换成 character_set_results 编码,然后再转换成每个字段编码保存。当然,编码一样就不转换了,character_set_client的值是binary也相当于表示跟 character_set_connection编码一样,不用转换了。

OK,上面这个语句是没问题的,只是为了规范mysql发送和接收编码都是big5。问题在于发送的内容,用户提交的文章内容中间,有个字是在big5字 符集之外的,这种情况mysql就自动把内容截断了,只保存了前面部分,并提示警告:
mysql Warning: #1366 Incorrect string value ...

在实际应用中,一般不能指望用户去把这个字找出来并改成正常文字,但是一篇文章因为一个字错误就截断有代价太大了。我找了下,没发现mysql有发 现错误字符集就跳过继续保存后面内容的设置,但是mysql在自动转换字符集时候却是会尽量最大化转换。利用这个可以用以下两种快速解决方法

1、"SET character_set_connection=big5, character_set_results=big5, character_set_client=binary" 这句改成
"SET character_set_connection=utf8, character_set_results=big5, character_set_client=big5"
这样的话,保存数据时候,提交的sql编码是 big5,自动会转换成utf8,然后mysql发现数据表字段属性是big5,会再转换成big5保存。

2、把保存的数据表字符段属性改成utf8,这样的话,提交和连接编码都是big5,而保存的数据会变成utf8。而查询取出数据,因为 character_set_results=big5,会再从utf8转换成big5

其实这两种方法都是让mysql白白转换了两次编码(自己写程序去检查内容是否合法字符集也不见得效率高),之前全部一致用big5时候,是不需要 编码转换的,这时候假设有问题的字符串字符串:“测试x内容” (这里的x表示默认字符集外的字符),保存后会变成 “测试”。而mysql把big5转换成utf8再转回big5后,保存的是“测试?内容”。也就是说,非正常字符集的字符换成 ? 了,这样在一个长篇的文章里面,至少不会出现看了一半没有的情况。

mysql识别字符集在很多时候是实用的,不过也导致了这么一个问题,如果这个字符集里面每个字节的ascii码不是0到255可以任意保存的,都 存在字符集外的字没法保存的问题。建议mysql默认碰到这种情况就跳过这个字,继续保存后面内容,而不是截断了。

你可能感兴趣的:(数据库)