这就是我的连接设置方式:
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
我正在插入数千条记录,当文本包含 \xF0 时,我总是会收到此错误(即错误的字符串值总是以 \xF0 开头)。
该列的排序规则是 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 个字节的字符。
您可能还必须在 MySQL 配置文件中将服务器属性 character_set_server
设置为 utf8mb4
。 Connector/J defaults to 3-byte Unicode otherwise 似乎:
例如,要将 4 字节 UTF-8 字符集与 Connector/J 一起使用,请将 MySQL 服务器配置为 character_set_server=utf8mb4,并将 characterEncoding 排除在 Connector/J 连接字符串之外。然后,Connector/J 将自动检测 UTF-8 设置。
包含 \xF0
的字符串只是使用 UTF-8 的 characters encoded as multiple bytes。
虽然您的排序规则设置为 utf8_general_ci,但我怀疑 数据库、表甚至列的字符编码可能不同。他们是independent settings。尝试:
ALTER TABLE database.table MODIFY COLUMN col VARCHAR(255)
CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
用您的实际数据类型替换 VARCHAR(255)
file-encoding
参数调用 Java,例如 java -Dfile.encoding=UTF-8
或在 Tomcat(等)配置文件中添加适当的开关。
遇到同样的问题,用 utf8mb4
保存数据需要确保:
character_set_client、character_set_connection、character_set_results为utf8mb4:character_set_client和character_set_connection表示客户端发送语句的字符集,character_set_results表示服务器向客户端返回查询结果的字符集。请参阅字符集连接。表和列编码为 utf8mb4
对于 JDBC,有两种解决方案:
方案一(需要重启MySQL):
修改 my.cnf 如下并重启 MySQL: [mysql] default-character-set=utf8mb4 [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci
这可以确保数据库和 character_set_client, character_set_connection, character_set_results
默认为 utf8mb4
。
重新启动 MySQL 将表和列编码更改为 utf8mb4 停止在 jdbc 连接器中指定 characterEncoding=UTF-8 和 characterSetResults=UTF-8,因为这会将 character_set_client、character_set_connection、character_set_results 覆盖为 utf8
解决方案二(不需要重启MySQL):
将表和列编码更改为 utf8mb4,在 jdbc 连接器中指定 characterEncoding=UTF-8,因为 jdbc 连接器不支持 utf8mb4。像这样编写你的 sql 语句(需要将 allowMultiQueries=true 添加到 jdbc 连接器):'SET NAMES utf8mb4;INSERT INTO Mytable ...';
这将确保与服务器 character_set_client,character_set_connection,character_set_results
的每个连接都是 utf8mb4
。
另请参阅 charset-connection。
SELECT
查询,因为 set names utf8mb4; select ... from ...
永远不会产生 ResultSet
而是导致 ResultSet is from UPDATE. No Data.
错误。
我想结合几篇文章来完整回答这个问题,因为它看起来确实需要几个步骤。
以上@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
再次从上面的建议中删除所有 jdbc 连接 characterEncoding=UTF-8
和 characterSetResults=UTF-8
有了这个集合 -Dfile.encoding=UTF-8
似乎没有任何区别。
我仍然无法将国际文本写入数据库,并出现与上述相同的失败
现在使用这个 how-to-convert-an-entire-mysql-database-characterset-and-collation-to-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%')
在编辑器中复制粘贴输出全部替换 |连接到正确的数据库时,没有任何内容回传到 mysql。
这就是所有必须做的,而且似乎对我有用。不是 -Dfile.encoding=UTF-8
未启用,它似乎按预期工作
E2A 仍有问题?我当然在生产中,所以事实证明你确实需要检查上面所做的事情,因为它有时不起作用,这是在这种情况下的原因和修复:
show create table user
`password` varchar(255) CHARACTER SET latin1 NOT NULL,
`username` varchar(255) CHARACTER SET latin1 NOT NULL,
您可以看到一些仍在尝试手动更新记录的拉丁语:
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)
简而言之,我必须减小该字段的大小才能使更新生效。
现在当我运行时:
mysql> ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
一切正常
ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;
,那么当我最后一次运行它时,所有字段都不再定义字符集。所以上面的密码变成了 password
varchar(255) NOT NULL,(与编码无关)。这意味着最后一个命令必须让 mysql 查找实际的表定义是什么,因为现在表默认情况下,字段不再需要它 - 我认为它们保留字符集只是因为在整个表更新的转储期间它无法更新它,因此它处于该状态
就我而言,我尝试了上述所有方法,但没有任何效果。我很确定,我的数据库如下所示。
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;
事实证明,列字符集是拉丁文。这就是为什么我无法将中文插入数据库的原因。
ALTER TABLE company CONVERT TO CHARACTER SET utf8;
那可能对你有帮助。 :)
我在 Rails 项目中遇到了同样的问题:
Incorrect string value: '\xF0\xA9\xB8\xBDs ...' for column 'subject' at row1
解决方案 1:在保存到 db 之前通过 Base64.encode64(subject)
将字符串转换为 base64 并在从 db 获取之后使用 Base64.decode64(subject)
解决方案2:
第 1 步:更改主题列的字符集(和排序规则)
ALTER TABLE t1 MODIFY
subject VARCHAR(255)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
第 2 步:在 database.yml 中使用
encoding :utf8mb4
做就是了
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 ;
假设您使用 phpmyadmin 来解决此错误,请按照下列步骤操作:
phpMyAdmin your_table "Structure tab" 将字段的排序规则从 latin1_swedish_ci (或任何它)更改为 utf8_general_ci
它主要是由于一些unicode字符引起的。就我而言,它是卢比货币符号。
为了快速解决这个问题,我必须找出导致这个错误的角色。我将整个文本复制粘贴到 vi 等文本编辑器中,并用文本替换了令人不安的字符。
我只想对一个字段应用更改,您可以尝试序列化该字段
class MyModel < ActiveRecord::Base
serialize :content
attr_accessible :content, :title
end
我的 PLAY Java 应用程序有这个问题。这是我对该异常的堆栈跟踪:
javax.persistence.PersistenceException: Error[Incorrect string value: '\xE0\xA6\xAC\xE0\xA6\xBE...' for column 'product_name' at row 1]
at io.ebean.config.dbplatform.SqlCodeTranslator.translate(SqlCodeTranslator.java:52)
at io.ebean.config.dbplatform.DatabasePlatform.translate(DatabasePlatform.java:192)
at io.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:83)
at io.ebeaninternal.server.persist.dml.DmlBeanPersister.insert(DmlBeanPersister.java:49)
at io.ebeaninternal.server.core.PersistRequestBean.executeInsert(PersistRequestBean.java:1136)
at io.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:723)
at io.ebeaninternal.server.core.PersistRequestBean.executeNoBatch(PersistRequestBean.java:778)
at io.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:769)
at io.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:456)
at io.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:406)
at io.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:393)
at io.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1602)
at io.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1594)
at io.ebean.Model.save(Model.java:190)
at models.Product.create(Product.java:147)
at controllers.PushData.xlsupload(PushData.java:67)
at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$40(Routes.scala:690)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:134)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:133)
at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$8$$anon$2$$anon$1.invocation(HandlerInvoker.scala:108)
at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:88)
at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:31)
at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:138)
at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:655)
at scala.util.Success.$anonfun$map$1(Try.scala:251)
at scala.util.Success.map(Try.scala:209)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:289)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run$$$capture(Promise.scala:60)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala)
at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:56)
at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70)
at play.core.j.HttpExecutionContext.execute(HttpExecutionContext.scala:48)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete(Promise.scala:368)
at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete$(Promise.scala:367)
at scala.concurrent.impl.Promise$KeptPromise$Successful.onComplete(Promise.scala:375)
at scala.concurrent.impl.Promise.transform(Promise.scala:29)
at scala.concurrent.impl.Promise.transform$(Promise.scala:27)
at scala.concurrent.impl.Promise$KeptPromise$Successful.transform(Promise.scala:375)
at scala.concurrent.Future.map(Future.scala:289)
at scala.concurrent.Future.map$(Future.scala:289)
at scala.concurrent.impl.Promise$KeptPromise$Successful.map(Promise.scala:375)
at scala.concurrent.Future$.apply(Future.scala:655)
at play.core.j.JavaAction.apply(JavaAction.scala:138)
at play.api.mvc.Action.$anonfun$apply$2(Action.scala:96)
at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:304)
at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
at scala.concurrent.impl.CallbackRunnable.run$$$capture(Promise.scala:60)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:43)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.sql.SQLException: Incorrect string value: '\xE0\xA6\xAC\xE0\xA6\xBE...' for column 'product_name' at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at io.ebeaninternal.server.type.DataBind.executeUpdate(DataBind.java:82)
at io.ebeaninternal.server.persist.dml.InsertHandler.execute(InsertHandler.java:122)
at io.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:73)
... 59 more
我试图使用 io.Ebean 保存记录。我通过使用 utf8mb4 排序规则重新创建我的数据库来修复它,并应用播放进化来重新创建所有表,以便所有表都应该使用 utf-8 排序规则重新创建。
CREATE DATABASE inventory CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
提示:在 AWS RDS 上,您需要一个带有参数的 MySQL 数据库的新参数组(而不是编辑 my.cnf)
collation_connection:utf8mb4_unicode_ci
collation_database:utf8mb4_unicode_ci
collation_server: utf8mb4_unicode_ci
character_set_client: utf8mb4
character_set_connection:utf8mb4
字符集数据库:utf8mb4
character_set_results:utf8mb4
character_set_server: utf8mb4
注意:character_set_system 保持“utf8”
这些 SQL 命令不能永久工作 - 仅在会话中:
set character_set_server = utf8mb4;
set collation_server = utf8mb4_unicode_ci;
我的解决方案是将列类型从 varchar(255) 更改为 blob
如果您正在创建一个新的 MySQL 表,您可以在创建时指定所有列的字符集,这为我解决了这个问题。
CREATE TABLE tablename (
<list-of-columns>
)
CHARSET SET utf8mb4 COLLATE utf8mb4_unicode_ci;
您可以阅读更多详细信息:https://dev.mysql.com/doc/refman/8.0/en/charset-column.html
这不是推荐解决方案..但值得分享。由于我的项目是将 DBMS 从旧的 Mysql 升级到最新的(8)。但我不能改变表结构,只能改变 DBMS 配置(mysql)。 mysql服务器的解决方案。
在 Windows mysql 8.0.15 上测试 mysql 配置搜索
sql-mode="....."
取消注释。或者在我的情况下,只需输入/添加
sql-mode="NO_ENGINE_SUBSTITUTION"
为什么不推荐解决方案。因为如果您使用 latin1(我的情况).. 数据插入成功但内容不成功(mysql 不响应错误!!)。例如,您输入这样的信息
布拉\x12
它保存
bla [](框)
好的..对于我的问题..我可以将字段更改为UTF8 ..但是有一个小问题..请参阅上面关于其他解决方案的答案失败,因为单词没有插入,因为包含超过2个字节(cmiiw)..这个解决方案使您的插入数据成为框。合理的是使用 blob .. 你可以跳过我的回答。
与此相关的另一个测试是.. 在保存之前在您的代码上使用 utf8_encode。我在 latin1 上使用它是成功的(我没有使用 sql-mode)!与使用 base64_encode 的上述答案相同。
我建议分析您的表格要求并尝试从其他格式更改为 UTF8
您需要在 meta html 和服务器中设置 utf8mb4 更改表并将排序规则设置为 utf8mb4
删除架构并使用 utf8mb4
字符集重新创建它解决了我的问题。
我还必须删除并重新创建所有数据库的存储过程(以及函数),以便它们在 utf8mb4 的新字符集中执行。
跑:
SHOW PROCEDURE STATUS;
…查看哪些过程尚未更新到服务器的新 character_set_client、collation_connection 和 Database Collation 值。
但是,需要注意的是mysql连接器驱动版本必须早于5.1.47及更高版本。
在最终尝试了许多查询之后,这行得通
ALTER TABLE
table_name
CHANGE column_name column_name
varchar(256)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
不定期副业成功案例分享
character_encoding_server
不是有效的 MySQL 配置变量名称。除了个别列之外,我还尝试将character_set_server
设置为utf8mb4
,但它没有改变任何东西。