试图通过JDBC将UTF-8插入到MySQL中时出现“字符串值不正确”?

ltskdhd1  于 2022-09-18  发布在  Java
关注(0)|答案(21)|浏览(228)

我的连接是这样设置的:
Connection conn = DriverManager.getConnection(url + dbName + "?useUnicode=true&characterEncoding=utf-8", userName, password);

在为表添加行时,我得到了以下错误:
Incorrect string value: 'xF0x90x8Dx83xF0x90...' for column 'content' at row 1

我插入了数千条记录,当文本包含\xF0(即不正确的字符串值始终以\xF0开头)时,我总是会收到这个错误。

该列的排序规则为utf8_General_ci。

这可能是什么问题?

q9rjltbz

q9rjltbz16#

只要做就行了

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 ;
cnwbcb6i

cnwbcb6i17#

我在我的Rails项目中遇到了同样的问题:

Incorrect string value: 'xF0xA9xB8xBDs ...' for column 'subject' at row1

解决方案1:在保存到数据库之前,使用Base64.encode64(subject)将字符串转换为Base64,并在从数据库提取后使用Base64.decode64(subject)

解决方案2:

步骤1:通过以下方式更改主题列的字符集(和排序规则

ALTER TABLE t1 MODIFY
subject VARCHAR(255)
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

步骤2:在database ase.yml中使用

encoding :utf8mb4
isr3a4wc

isr3a4wc18#

在我的情况下,我尝试了上面的所有方法,都没有奏效。我非常确定,我的数据库如下所示。

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;

这可能会对你有帮助。:)

k4emjkb1

k4emjkb119#

我想结合几个帖子来完整地回答这个问题,因为它看起来确实是几个步骤。

1.以上来自@Madtraey的建议

/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-8characterSetResults=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%')

在连接到正确的数据库时,在编辑器中复制粘贴输出替换ALL|WITH NOT POST回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

这一切都奏效了

sauutmhj

sauutmhj20#

遇到同样的问题,要使用utf8mb4保存数据,需要确保:

character_set_client, character_set_connection, character_set_resultsutf8mb4character_set_clientcharacter_set_connection表示客户端发送语句的字符集,character_set_results表示服务器向客户端返回查询结果的字符集。
参见charset-connection
1.表列编码为utf8mb4

对于JDBC,有两种解决方案:

方案一(需要重启MySQL):

1.修改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_resultsutf8mb4

1.重启MySQL
1.将表和列的编码更改为utf8mb4
1.停止在JDBC连接器中指定characterEncoding=UTF-8characterSetResults=UTF-8,因为这将覆盖character_set_clientcharacter_set_connectioncharacter_set_resultsutf8

方案二(无需重启MySQL):

1.将表和列的编码更改为utf8mb4
在JDBC连接器中指定characterEncoding=UTF-8,导致JDBC连接器不支持utf8mb4
1.这样编写您的SQL语句(需要将allowMultiQueries=true添加到JDBC连接器):

'SET NAMES utf8mb4;INSERT INTO Mytable ...';

这将确保到服务器character_set_client,character_set_connection,character_set_results的每个连接都是utf8mb4
另请参阅charset-connection

iqxoj9l9

iqxoj9l921#

包含\xF0的字符串只是使用UTF-8编码为多个字节的字符。

尽管您的排序规则设置为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)

相关问题