MySQL字符集及ERROR 1366 Incorrect string value错误分析

MySQL提供多级字符集机制,其字符集分为服务器字符集、数据库字符集、表字符集、列字符集以及连接字符集和返回结果字符集等等。因此,对字符集进行设置可能会影响到数据库的正常使用,尤其会影响到涉及中文字符的那些操作。

1.引言

(1)字符集:字符集是一套符号和编码。比如对字母a, b, c进行编码,分别编码为0, 1, 2。这些字符和编码组成的字符-编码对的集合就是一个字符集。

(2)校对规则:同一字符集内的字符比较规则称为校对规则。

2.对字符集的相关操作

(1)显示MySQL服务器支持的字符集:
mysql> SHOW CHARACTER SET;

(2)显示某个字符集的校对规则:
mysql> SHOW COLLATION LIKE ‘utf8%’;

(3)显示字符集相关的系统变量:
mysql> SHOW VARIABLES LIKE ‘character%’;

其中,各变量代表的意义:
(a)character_set_client:客户端来源数据使用的字符集;
(b)character_set_connection:连接层字符集;
(c)character_set_database:当前选中数据库的默认字符集;
(d)character_set_results:查询结果字符集;
(e)character_set_server:默认的内部操作字符集;
(f)character_set_system:系统元数据(字段名等)字符集;

(4)显示字符集校对规则相关的系统变量:
mysql> SHOW VARIABLES LIKE ‘collation%’;

3.多级字符集

(1)服务器字符集和校对

服务器字符集和校对可以使用–default-character-set设置字符集,并且在字符集后面添加默认校对规则–default-collation。比如:
shell> mysqld –defualt-character-set=latinl

当前服务器的字符集和校对规则对应作系统变量character_set_server和collation_server,在运行时也可以改变这些变量的值。

(2)数据库字符集和校对

每一个数据库有一个数据库字符集和校对规则,CREATE DATABASE和ALTER DATABASE语句有一个可选的子句来指定数据库字符集和校对规则:

如果没有指定任何字符集和校对规则,则采用服务器字符集和服务器校对规则。

(3)表字符集和校对

每一个表有一个表字符集和校对规则,CREATE TABLE和ALTER TABLE语句有一个可选的子句可以用来对其进行设置:

如果没有指定任何字符集和校对规则,则采用服务器字符集和服务器校对规则。

(4)列字符集和校对

每一个“字符”列(如CHAR, VARCHAR或TEXT类型的列)有一个列字符集和校对规则。列定义语法有一个可选子句来指定列字符集和校对规则:

如果没有指定任何字符集和校对规则,则采用表字符集和服务器校对规则。

(5)SET NAMES charset_name

SET NAMES charset_name语句与下面三个语句是等价的:

4. ERROR 1366

调试程序中,有如下报错:
ERROR 1366 Incorrect string value: ‘\xD2\xFD\xC7\xE6ME…’ for column ‘mark’ at row 1

(1)背景

源程序调用mysql C API进行插入操作,其中插入的字段包含中文字符,每次执行时都会报错:ERROR 1366 Incorrect string value: ‘\xD2\xFD\xC7\xE6ME…’ for column ‘mark’ at row 1

错误说单引号括着的十六进制表示的字符值无法插入表字段mark中去,查看源代码发现某个字段待插入的数据为中文。于是尝试将中文数据改为英文,遂插入成功。因此判断是中文编码问题导致的错误。

此为背景。

(2)调试过程

查看服务器、数据库、表以及表字段的字符集,均为utf8===》猜测mysql相关字符集设置应该没有问题;

于是在mysql的命令行界面尝试对该字段插入中文数据,成功插入===》确定mysql字符集设置没有问题的结论。

转而查看源程序:发现源代码文件的编码格式gb2312。——与mysql服务设置的utf8编码不同,因此造成了插入中文数据失败。

(3)解决办法

一种解决办法是顺应GB2312,在源程序每次调用接口函数进行INSERT操作之前调用一次SET NAMES gbk;(set names charset_name等同于哪三个操作还记得吗?查看前文)。

另一种方法是将包含待插入中文数据的源文件转码为utf8编码(notepad++可以实现转码)即可。

(4)结论

造成这个错误的主要原因是,在windows和linux两种系统下切换着工作并忘记转换文件的编码方式导致。

发表评论

电子邮件地址不会被公开。 必填项已用*标注