“字符串值不正确:”将 UTF8 文本插入 latin1 列时出现 MySQL 问题

Posted

技术标签:

【中文标题】“字符串值不正确:”将 UTF8 文本插入 latin1 列时出现 MySQL 问题【英文标题】:"Incorrect string value:" MySQL issue when inserting UTF8 text into a latin1 column 【发布时间】:2016-08-31 22:51:27 【问题描述】:

我在生产中有这个 mysql 表,它是 charset latin1_swedish_ci (aka latin1)。

现在,有一个 UTF-8 格式的传入内容(String : "\ud55c\ubc24\uc758")需要插入到名为 keywords 的 TEXT 列字段中桌子。

当我尝试执行 INSERT 时,我收到此错误:

Incorrect string value: '\xED\x95\x9C\xEB\xB0\xA4...' for column 'keywords' at row 1

我在我的 Java 代码中尝试了各种方法来尝试从 UTF8 转换为 ISO-8859-1,如下所示,但我仍然遇到同样的错误:

String convertedString = new String(originalString.getBytes("UTF-8"), "ISO-8859-1");

我知道 *** 上有一些解决方案提到将 MySQL 表的字符集从 latin1 更改为 UTF8,但遗憾的是我不能这样做,因为这是一个实时生产 MySQL 主服务器,而且它一直使用 latin1。

有没有人有任何建议来解决这个“不正确的字符串值”错误?

谢谢 是

【问题讨论】:

您需要将 in Java 的编码从 usc2 更改为 utf8。 ISO-8859-1 与您展示的内容无关。你希望한밤,对吗? 嗨 Rick James,感谢您的快速回复。将编码从usc2更改为utf8是什么意思?对不起,我没有关注。是的,我想去한밤 所以曾经有一个旧的 Python 脚本会从另一个 MySQL 数据库(在 utf-8 中)读取这个 unicode 文本并将其写入这个 latin1 MySQL 数据库,这个文本会显示为 í •œë°¤ì˜ 如果我能弄清楚如何在我的 Java 代码中将“\ud55c\ubc24\uc758”转换为“한밤옔,那么我很好 【参考方案1】:

您尝试做的事情根本不可能,除非 utf8 字符串中的字符也恰好在 latin1 中具有表示形式......并且 latin1 是一个很小的单字节字符集(少于 256 个可能的字符,总计),因此绝大多数有效的 utf8 字符没有等效的 latin1 表示。

您不能在该列的字符集不支持的列中存储任何字符。这不是从一个“转换”到另一个的问题。

如果你需要 unicode,你至少需要一个 utf8 列,修改表是唯一的选择。尝试不这样做就像尝试将负数存储在无符号整数列中。无符号整数不能为负数——这不是转换问题。

这对于任何支持字符数据类型的 RDBMS 都是正确的,并且不是特定于 MySQL 的限制。

【讨论】:

嗨迈克尔,感谢您的回复。所以曾经有一个旧的 Python 脚本会从另一个 MySQL 数据库(在 utf-8 中)读取这个 unicode 文本并将其写入这个 latin1 MySQL 数据库,这个文本将显示为 한밤ì~ 如果我可以弄清楚如何在我的 Java 代码中将“\ud55c\ubc24\uc758”转换为“한밤ì∼”,那么我很好【参考方案2】:

한밤한밤 的 Mojibake——这就是它在某个阶段被转换为 latin1 的地方。但是\ud55c\ubc24 是 Unicode。 Python处于什么模式?你一开始有这个吗?

# -*- coding: utf-8 -*- 

More Python checklist.

更多

utf8 是首选; euckr 是可能的。但是...问题不在于选择字符集,而在于在整个应用程序中指定该字符集时保持一致。

你在使用 Python 吗?它被标记为 Java?

对于 Java/JDBC,您需要在 getConnection() 调用中使用 ?useUnicode=yes&characterEncoding=UTF-8

你需要这些:

客户端中的字节需要是utf8,如十六进制ED959C。 (韩语字符在 utf8 中都是 3 个字节。) 客户端和服务器之间的连接需要是utf8。连接后立即执行SET NAMES utf8 是另一种方法。 列/表必须是CHARACTER SET utf8。 如果您使用的是html,则需要<meta charset=UTF-8>

对于韩语,utf8mb4utf8 一样好。检查上面这 4 个项目符号,并向我们“证明”您正在执行所有这些项目。

对于 JSP 和 Java Servlet,advice 略有不同是有保证的。

【讨论】:

嗨 Rick,是的,我确实在 Python 文件的顶部看到了“# -- coding: utf-8 --” 清单链接中有什么有用的吗? 不幸的是还没有,但我确实尝试在 Java 代码中使用不同的转换。当我尝试使用 "new String(keywords.getBytes("UTF-8"), "Cp1252") " 转换为 Cp1252 而不是 ISO-8859-1 时,我注意到一些有趣的事情 在 Java 中,当我将 Unicode 韩语字符转换为 Cp1252 时,我得到 한밤ì 触发“不正确的字符串值:'\xEF\xBF\xBD\xCB\x9CT。 ..' 对于第 1 行的列 'keywords'" 错误。但是,当它由 Python 写入 MySQL 时,它是 한밤ì ,并且可以很好地写入 MySQL latin1 列!唯一的区别是最后一个字符,我仍在试图弄清楚如何在 Java 中获得与 Python 中相同的结果 CP1252 有 256 个不同的字符。韩国人大约有11,000人。说白了,CP1252不能表示韩语,所以不要用CP1252表示韩文。

以上是关于“字符串值不正确:”将 UTF8 文本插入 latin1 列时出现 MySQL 问题的主要内容,如果未能解决你的问题,请参考以下文章

将 UTF-8 编码的字符串插入 UTF-8 编码的 mysql 表失败​​,并显示“字符串值不正确”

日期时间格式无效:1366 字符串值不正确

忽略插入错误

带有消息“SQLSTATE [22007]”的未捕获异常“PDOException”:日期时间格式无效:1366 字符串值不正确

SQLSTATE[22007]:无效的日期时间格式:1366 字符串值不正确,html_entity_decode 函数

SonarQube Server 6.1 错误:字符串值不正确:'\xF0\x9F\x92\x9A S