【问题标题】:migrating mysql 5.5.62 database schema to mysql 8.0.27 - sporadic error java.sql.SQLException: Incorrect string value: '\xE2\x80\x8B' for column将 mysql 5.5.62 数据库模式迁移到 mysql 8.0.27 - 偶发错误 java.sql.SQLException:字符串值不正确:列的“\xE2\x80\x8B”
【发布时间】:2021-11-20 13:26:53
【问题描述】:

正在将架构从 mysql 5.5.62 迁移到 mysql 8.0.27。

我的做法是从所需架构的 5.5.62 获取 mysqldump,然后将转储导入 mysql 8.0.27。

导入的数据一切正常,但是从 java 应用程序在其中一个表中插入失败并出现以下错误:java.sql.SQLException: Incorrect string value: '\xE2\x80\x8B' for column

mysql8.0.27 db中的字符集如下

mysql> show variables like 'char%';
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8mb4                        |
| character_set_connection | utf8mb4                        |
| character_set_database   | utf8mb4                        |
| character_set_filesystem | binary                         |
| character_set_results    | utf8mb4                        |
| character_set_server     | utf8mb4                        |
| character_set_system     | utf8mb3                        |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.00 sec)

mysql 5.5.62 db中的字符集如下

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

通过hibernate执行插入的java应用程序中使用的jdbc连接器是mysql-connector-java-8.0.27.jar

当用户在 mysql 5.5.62 服务器中创建模式/表时没有做任何特别的事情时,为什么用户需要明确地使用 character_sets(当将数据迁移到更高版本的 mysql 时)? 对于处理此类问题的最佳方法有什么想法吗?

2021 年 11 月 22 日编辑

经过几天的努力,我终于知道“罪魁祸首”是 Microsoft Azure API 返回的特定文本,末尾有一个字符“\u200b”。只有当我在 PostMan 中检查 Azure API 返回的响应的原始文本时,我才能注意到这一点......

这个'\u200b'(零宽度空间)的描述在这里解释得很清楚 https://www.fileformat.info/info/unicode/char/200B/index.htm

即使这个字符的 UTF-8(十六进制)编码也是“0xE2 0x80 0x8B (e2808b)”。这正是 SQL 异常中存在的内容 java.sql.SQLException:不正确的字符串值:列的'\xE2\x80\x8B'

所以对我来说,我认为我不需要通过调整数据库字符集配置来处理这个问题,因为可以简单地从响应中删除这个字符并在插入数据库之前处理文本。

但是我想保持这篇文章活跃,因为我浪费了太多精力来解决问题,认为这是与数据库的字符集配置有关的问题。

说了这么多之后,我尝试从 MySQLWorkBench 执行插入查询,使用这个字符到 mysql 5.5 的表中,它插入数据但警告 1 行受影响,1 个警告:1366 不正确的字符串value: '\xC2\x80' for column
请注意,只有 db 发出警告,而不是错误

当我尝试对 mysql 8.0 执行相同的插入操作(通过 MySQLWorkBench)DB 返回错误错误代码:1366。不正确的字符串值:列的'\xC2\x80' .

在实际场景中,如果有人需要在表格列中保持原样,那么他/她应该如何做到这一点?有什么想法吗?

【问题讨论】:

    标签: java mysql


    【解决方案1】:

    Hex E2808B 是 UTF 编码中的“零宽度空间”。

    请为有问题的表提供SHOW CREATE TABLE,并指明存储到哪一列。

    通常情况下,我会将您指向 Trouble with UTF-8 characters; what I see is not what I stored 以进行进一步诊断,并指向 http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases 以了解如何解决您遇到的任何情况。

    你能告诉我们更多的上下文吗?这就是这 3 个十六进制字符周围的字符。

    我无法完全判断这是“双重编码”情况还是 UTF-8 文本在 INSERTed 时被错误地声明为 latin1。如果您能找到字符串的插入方式,那可能会有所帮助。

    C280 闻起来像一个错误编码的 Eurosign。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-18
      • 2015-05-12
      • 2019-10-14
      • 2015-06-01
      • 1970-01-01
      • 2013-10-10
      • 2012-02-01
      • 2012-11-08
      相关资源
      最近更新 更多