ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column XXX at row 1

在用以下方法之前,请先执行下面命令查看。

    show variables like 'character%';  ——查看所有编码方式

    show create table table_name;   ——查看某个表格的编码方式

    status  ——查看

查看修改mysql编码方式
 
MySQL的默认编码是Latin1,不支持中文,要支持中午需要把 数据库的默认编码修改为gbk或者utf8。 
 
1、需要以root用户身份登陆才可以查看数据库编码方式(以root用户身份登陆的命令为:>mysql -u root –p,之后两次输入root用户的密码),查看数据库的编码方式命令为: 
>show variables like 'character%'; 
+--------------------------+----------------------------+ 
| Variable_name | Value | 
+--------------------------+----------------------------+ 
| character_set_client | latin1 | 
| character_set_connection | latin1 | 
| character_set_database | latin1 | 
| character_set_filesystem | binary | 
| character_set_results | latin1 | 
| character_set_server | latin1 | 
| character_set_system | utf8 | 
| character_sets_dir | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 
从以上信息可知数据库的编码为latin1,需要修改为gbk或者是utf8; 
其中,character_set_client为客户端编码方式;character_set_connection为建立连接使用的编码;character_set_database数据库的编码; 
character_set_results结果集的编码; 
character_set_server数据库服务器的编码; 
只要保证以上四个采用的编码方式一样,就不会出现乱码问题。 
另一个查看数据库编码的命令: 
>show variables like ‘collation%’; 






一、网上的解决方案很多,但是试了几个都没成功。能改的地方都改了,my.ini里两个地方[mysql]和[mysqld]都改成了gbk,又多此一举跑MySQLInstanceConfig.exe里也设置了默认字符集为gbk,还有在数据库里也使用了charset gbk来更改字符集,可无一例外中文还是插不进去。

最后在http://youshini.iteye.com/blog/1073053上又找到一个解决方案,在数据库里使用了alter table content modify author varchar(30) character set gbk;这句话之后成功插入了中文!心中那个鸡冻啊。

现在知道了,前面把my.ini或者在MySQLInstanceConfig.exe里改变了编码字符集之后只对以后创建的表起作用,对于以前创建的表要使用alter table content modify author varchar(30) character set gbk才可以插入中文,当然,嫌这样一个字段一个字段的修改太麻烦可以使用ALTER TABLE OLD_TABLE CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]直接对整个表操作。
。这里把问题及解决方案贴出方便后来人!个人总结出mysql数据库要正常插入中文需要三个地方字符集一致:

1、mysql的初始化字符集(my.ini中修改)

2、某个具体的database中通过charset gbk或者\c gbk修改

3、最后这个不是必须的,只是如果在中途改了以上两个字符集才需要在此修改。把表中的字段改成和上面两种一样的字符集:通过ALTER TABLE OLD_TABLE CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]修改

 

 

二、最后再附上一篇整体概述的设置mysql支持中文的文章,转于51cto.com

MySQL数据库默认编码已经是utf8了, default-character-set = utf8,可是向数据库中表中插入中文时,却老是出现 ....\xB5\xA5\xD1\xA1 for column...这样的错误,经过查阅网上类型的错误后,发现一个很奇妙的现象,接下来我们就来开始介绍。

1)、在安装数据库时就设定字符集编码为utf8的环境下

1.在当前字符集编码为:

1 Server characterset:    utf8  

2  

3 Db      characterset:    utf8  

4  

5 Client  characterset:    utf8  

6  

7 Conn.  characterset:    utf8 

下创建数据库:

(1)插入中文数据,操作不能成功。

(2)修改字符集编码为:

8 Server characterset:    utf8  

9  

10 Db       characterset:   utf8  

11  

12 Client  characterset:    gbk  

13  

14 Conn.  characterset:    gbk 

插入中文数据,显示正常。

2)、在安装数据库时就设定字符集编码为gbk的环境下

1.当前字符集编码是:

15 Server characterset:    gbk  

16  

17 Db      characterset:    gbk  

18  

19 Client  characterset:   gbk  

20  

21 Conn.  characterset:   gbk  

下创建数据,插入中文数据,操作正常,显示正常。

2.当前字符集编码为utf8:

22 Server characterset:   gbk  

23  

24 Db      characterset:    utf8  

25  

26 Client  characterset:   utf8  

27  

28 Conn.  characterset:   utf8 

3.当前字符集编码为utf8:

29 Server characterset:    gbk  

30  

31 Db      characterset:    gbk  

32  

33 Client  characterset:   utf8  

34  

35 Conn.  characterset:   utf8 

插入中文数据,操作不能执行。

结论:要想能向数据库正常插入中文,必须满足以下条件:

1.要把字符集设定为能支持中文的gbk或则utf8;

2.把数据库的Client Characterset和Conn. Characterset的字符集都设定为gbk;

根据上面的提示 ,我更改了:

36 SET  character_set_client=gbk;  

37  

38 SET character_set_connection=gbk; 

之后再尝试想数据库插入中文,这时没有出错,能插入可是查询出来是乱码。

最后再更改; 

39 SET character_set_results=gbk; 

这样之后,所有的问题都解决了,能正常插入也能正常显示了。(http://hi.baidu.com/vanadium362/item/ffa64caed7ee5eae29ce9d32)




最后各种数据编码问题:http://bbs.csdn.net/topics/190115814







alter table dig_t_devportal_inquiry character set utf8;

SET  character_set_client=gbk;

 SET character_set_connection=gbk;

show create table dig_t_devportal_inquiry;

alter database dig character set utf8;

 status


另一篇文档

你是否遇到过类似以下错误?

java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x9C' for column 'content' at row 1.

产生这种异常的原因在于,mysql中的utf8编码最多会用3个字节存储一个字符,如果一个字符的utf8

编码占用4个字节(最常见的就是ios中的emoji表情字符),那么在写入数据库时就会报错。

mysql从5.5.3版本开始,才支持4字节的utf8编码,编码名称为utf8mb4(mb4的意思是max bytes 4),这种编码方式最多用4个字节存储一个字符。

要想证明这个问题,可以执行以下sql:

select * from
information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like 'utf8%'

结果如图:

因此,要解决上述异常的发生,需要使用utf8mb4编码。


解决数据库编码后,还需要解决客户端Connection连接对象使用的编码问题。

调用创建的Connection对象执行以下sql:

conn.createStatement().execute("SET names 'utf8mb4'");

如果项目中使用了DataSource数据源,只需要对数据源进行相关配置即可,这里以apache的DBCP数据源为例讲解,在spring框架下配置如下:


	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver">property>
		<property name="url" value="jdbc:mysql://${${data-source.prefix}.data-source.host-name}:3306/${${data-source.prefix}.data-source.db-name}?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true" />
		<property name="username" value="${${data-source.prefix}.data-source.username}" />
		<property name="password" value="${${data-source.prefix}.data-source.password}" />
		<property name="maxActive" value="150" />
		<property name="maxIdle" value="2" />
		<property name="testOnBorrow" value="true" />
		<property name="testOnReturn" value="true" />
		<property name="testWhileIdle" value="true" />
		<property name="validationQuery" value="select 1" />
		
		<property name="connectionInitSqls">
			<list>
				<value>set names 'utf8mb4'value>
			list>
		property>
	bean>

以下解释引用自mysql参考手册:

SET NAMES 'charset_name'

SET NAMES显示客户端发送的SQL语句中使用什么字符集。

因此,SET NAMES 'utf8mb4'语句告诉服务器:“将来从这个客户端传来的信息采用字符集utf8mb4”。它还为服务器发送回客户端的结果指定了字符集。(例如,如果你使用一个SELECT语句,它表示列值使用了什么字符集。)


SET NAMES 'x'语句与这三个语句等价:


mysql> SET character_set_client = x;

mysql> SET character_set_results = x;

mysql> SET character_set_connection = x;

执行完此sql语句后,通过此连接对象后续创建的Statement都会成功地执行了。


讲到这里,问题已经得到完美解决,但是我又联想到一个新的问题:

jvm虚拟机运行时,内存中的字符串采用utf-16编码,对于ios中的emoji表情这种用4字节utf-8编码存储的字符,在java运行时又是怎样存储的呢?

于是,我找了一个emoji字符(4个字节的值分别为0xf0,0x9F,0x92,0x9c),做了以下试验。

byte[] bytes = new byte[] { (byte0xf0, (byte0x9F, (byte0x92, (byte0x9c };
		String s = new String(bytes, Charset.forName("utf-8"));
		System.out.println("length:"+s.length());
		for (int i=0;iint ch = s.charAt(i);
			System.out.println("0x"+Integer.toHexString(ch));
		}

执行结果如下:

ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column XXX at row 1_第1张图片

由结果可以看出,unicode值(也叫codePoint码点,后面介绍API会用到)大于0xffff的单个字符,jvm内部占用2个char的长度(也就是4个字节)存储。

所有大于0xffff的字符,全都在UTF编码表的辅助平面内(域辅助平台对应的是基础平面,简称BMP)。因此对于String中的某个char,是基础平面字符,还是辅助平面字符的一部分,也很好做出判断。下面介绍java.lang.Character中的一些API:

以下描述中,码点即是字符的unicode值

Character中API
描述
isValidCodePoint(int codePoint):boolean 判断输入码点是否是有效的,所有属于UTF定义平面的码点都是有效的
isBmpCodePoint(int codePoint):boolean 判断输入码点是否属于基础平面,即:0x0000~0xffff
isSupplementaryCodePoint(int codePoint):boolean 判断输入码点是否属于辅助平面,即:码点>0xffff
isSurrogate(char ch):boolean 判断输入的字符是否辅助平面字符的一部分

获取String中某个字符的码点也很容易,调用String.codePointAt(int index):int即可。


最后,关于unicode、UCS-2、UCS-4、UTF-8、UTF-16编码之间的关系,请读者自行百度。文章太多了,在此就不多做介绍了。


参考资料:

  • mysql utf8mb4与emoji表情:

    http://my.oschina.net/wingyiu/blog/153357

  • 关于 MySQL UTF8 编码下生僻字符插入失败/假死问题的分析

    http://my.oschina.net/leejun2005/blog/343353




你可能感兴趣的:(mysql)