尝试通过JDBC将UTF-8插入到MySQL中时出现“错误的string值”?
这是我的连接设置:
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);
而且在向表中添加一行时出现以下错误:
Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...' for column 'content' at row 1
我插入了成千上万的logging,当文本包含\ xF0时(即不正确的string值始终以\ xF0开头),我总是得到这个错误。
该列的sorting规则是utf8_general_ci。
可能是什么问题呢?
MySQL的utf8
只允许UTF-8中可以用3个字节表示的Unicode字符。 这里有一个需要4个字节的字符:\ xF0 \ x90 \ x8D \ x83( U + 10343 GOTHIC LETTER SAUIL )。
如果您有MySQL 5.5或更高版本,则可以将列编码从utf8
更改为utf8mb4
。 该编码允许以UTF-8格式存储占用4个字节的字符。
您可能还必须在MySQLconfiguration文件中将服务器属性character_set_server
设置为utf8mb4
。 看来连接器/ J默认为3字节的Unicode,否则 :
例如,要使用连接器/ J使用4字节的UTF-8字符集,请使用
character_set_server=utf8mb4
configurationMySQL服务器,并将characterEncoding
保留为Connector / J连接string。 Connector / J将自动检测UTF-8设置。
包含\xF0
的string只是使用UTF-8 编码为多个字节的字符 。
尽pipe您的sorting规则设置为utf8_general_ci,但我怀疑数据库,表格甚至列的字符编码可能不同。 他们是独立的设置 。 尝试:
ALTER TABLE database.table MODIFY COLUMN col VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
用你的实际数据types代替VARCHAR(255)
得到同样的问题,用utf8mb4保存数据需要确保:
-
character_set_client,character_set_connection,character_set_results是utf8mb4:character_set_client和character_set_connection表示客户端发送语句的字符集,character_set_results表示服务器向客户端返回查询结果的字符集。参见charset-connection
-
表和列编码是utf8mb4
对于JDBC,有两个解决scheme:
解决scheme一(需要重启MySQL):
1.像下面这样修改my.cnf并重新启动MySQL:
[MySQL的]
默认字符集= utf8mb4
的[mysqld]
字符集服务器= utf8mb4
核对服务器= utf8mb4_unicode_ci
这可以确保数据库和character_set_client,character_set_connection,character_set_results默认是utf8mb4。
2.将表格和列编码更改为utf8mb4
3.在jdbc连接器中指定characterEncoding = UTF-8和characterSetResults = UTF-8,导致这将覆盖character_set_client,character_set_connection,character_set_results to utf8
解决scheme二(不需要重启MySQL):
1.将表格和列编码更改为utf8mb4
2.在jdbc连接器中指定characterEncoding = UTF-8,导致jdbc连接器不支持utf8mb4。
3.像这样写你的sql语句(需要添加allowMultiQueries = true到jdbc连接器):
'SET NAMES utf8mb4; INSERT INTO Mytable …';
这将确保每个连接到服务器,character_set_client,character_set_connection,character_set_results是utf8mb4.Also看到字符集连接
就我而言,我尝试了以上的一切,没有任何工作。 我很确定,我的数据库如下所示。
mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper Connection id: 12 Current database: xxx Current user: yo@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.7.17-0ubuntu0.16.04.1 (Ubuntu) Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/run/mysqld/mysqld.sock Uptime: 42 min 49 sec Threads: 1 Questions: 372 Slow queries: 0 Opens: 166 Flush tables: 1 Open tables: 30 Queries per second avg: 0.144
所以,我在每个表格中查找列字符集
show create table company;
事实certificate,这个字符集是拉丁文的。 这就是为什么我不能在数据库中插入中文。
ALTER TABLE company CONVERT TO CHARACTER SET utf8;
这可能会帮助你。 🙂
我想结合几个post来做一个完整的答案,因为它似乎只是几个步骤。
- 以上build议由@madtracey
/etc/mysql/my.cnf
或/etc/mysql/mysql.conf.d/mysqld.cnf
[mysql] default-character-set=utf8mb4 [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] ## character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
再次从build议之上的所有jdbc连接characterEncoding=UTF-8
和characterSetResults=UTF-8
从他们删除
用这个设置-Dfile.encoding=UTF-8
似乎没有什么区别。
我仍然不能将国际文本写入数据库得到同样的失败,如上所述
现在使用这个如何转换为完整的mysql数据库字符集和整理到utf-8
更新所有数据库使用utf8mb4
ALTER DATABASE YOURDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
运行这个查询,给你什么需要被敲击
SELECT CONCAT( 'ALTER TABLE ', table_name, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ', 'ALTER TABLE ', table_name, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ') FROM information_schema.TABLES AS T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` AS C WHERE C.collation_name = T.table_collation AND T.table_schema = 'YOURDB' AND (C.CHARACTER_SET_NAME != 'utf8mb4' OR C.COLLATION_NAME not like 'utf8mb4%')
在编辑器中复制粘贴输出全部replace| 当连接到正确的数据库时没有任何回发到MySQL。
这就是所有必须做的,似乎都为我工作。 不是 – Dfile.encoding=UTF-8
未启用,它似乎按预期工作
E2A仍有问题? 我当然是在生产,所以事实certificate,你需要检查上面做了什么,因为它有时不起作用,这里是理由和修复在这种情况下:
show create table user `password` varchar(255) CHARACTER SET latin1 NOT NULL, `username` varchar(255) CHARACTER SET latin1 NOT NULL,
你可以看到一些仍在拉丁试图手动更新logging:
ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4; ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
那么让我们缩小它:
mysql> ALTER TABLE user change username username varchar(255) CHARACTER SET utf8mb4 not NULL; ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes mysql> ALTER TABLE user change username username varchar(100) CHARACTER SET utf8mb4 not NULL; Query OK, 5 rows affected (0.01 sec)
总之,我不得不减less这个领域的大小,以使更新工作。
现在当我运行:
mysql> ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4; Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0
这一切工作
它主要是由于一些unicode字符造成的。 在我的情况下,这是卢比货币符号。
要快速解决这个问题,我不得不发现导致这个错误的字符。 我复制粘贴整个文本在一个文本编辑器,如六,并用一个文本replace麻烦的人物。
做就是了
ALTER TABLE `some_table` CHARACTER SET = utf8 , COLLATE = utf8_general_ci ; ALTER TABLE `some_table` CHANGE COLUMN `description_with_latin_or_something` `description` TEXT CHARACTER SET 'utf8' NOT NULL ;
我在rails项目中遇到了同样的问题:
Incorrect string value: '\xF0\xA9\xB8\xBDs ...' for column 'subject' at row1
解决scheme1:保存到数据库之前,通过Base64.encode64(subject)
将string转换为base64,从数据库中获取后使用Base64.decode64(subject)
解决scheme2:
步骤1:更改主题栏的字符集(和sorting规则)
ALTER TABLE t1 MODIFY subject VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
第2步:在database.yml中使用
encoding :utf8mb4
我的解决scheme是将列types从varchar(255)更改为blob
我只是想只适用于一个领域的变化,你可以尝试序列化字段
class MyModel < ActiveRecord::Base serialize :content attr_accessible :content, :title end