在MySQL中如何将一个看起来像Réation
,l’Oreal
的干净数据分别变成这样的R'action
和L'Oreal
?
答案 0 :(得分:2)
这看起来像一个“双重编码”的例子。它是右手在谈论utf8的地方,而左手则在听latin1。参见Trouble with UTF-8 characters; what I see is not what I stored和另见http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases。
Réation
-> Réation
,撤消双重编码。
您还说R'action
吗?我想知道您是将é
输入为e'
还是'e
吗?
我还要假设您的意思是L’Oreal
? (请注意,使用“正确的单引号”代替“撇号”。)
首先,我们需要验证它实际上是普通的双重编码。
SELECT col, HEX(col) FROM ... WHERE ...
应该以{{1}}的十六进制形式给您:
Réation
(忽略间距。)
如果您获得了其中的三分之一,请继续回答我。 如果还有其他问题,请停止! -这个问题比我想象的还要复杂。
现在,看看双重编码修复程序是否可以修复它(修复之前):
52 E9 6174696F6E -- latin1 encoding
52 C3A9 6174696F6E -- utf8 encoding
52 C383 C2A9 6174696F6E -- double encoding
您需要防止它发生 并修复数据。 以下某些内容是不可逆的;在表的副本上对其进行测试!
您的情况是:SELECT col, CONVERT(BINARY(CONVERT(CONVERT(
BINARY(CONVERT(col USING latin1)) USING utf8mb4)
USING latin1)) USING utf8mb4)
FROM tbl;
,但其中包含utf8 / utf8mb4字节;修复字符集时,不留任何字节:
首先,让我们假设您具有tbl.col的声明:
CHARACTER SET latin1
然后在不更改字节的情况下转换列:
col VARCHAR(111) CHARACTER SET latin1 NOT NULL
注意:如果以ALTER TABLE tbl MODIFY COLUMN col VARBINARY(111) NOT NULL;
ALTER TABLE tbl MODIFY COLUMN col VARCHAR(111) CHARACTER SET utf8mb4 NOT NULL;
开头,请使用TEXT
作为中间定义。 (请确保其他规格相同-BLOB
,VARCHAR
等)
针对出现问题的每个表中的每一列执行该操作。
(在本次讨论中,我不区分utf8mb4和utf8。大多数文字都对它感到满意; Emoji和一些中文需要utf8mb4,而不仅仅是utf8。)
来自评论
NOT NULL
我的结论:首先,您有一些错误的配置。然后,您应用了一个或多个错误修复程序。您现在一团糟,我不敢尝试帮助您解开它。也就是说,混乱不只是简单的“双重编码”。
如果可能,请重新开始,确保在添加更多数据之前正确存储了一些测试数据。如果数据不好,请不要尝试修复该数据。退后并重新开始。有关正确设置的信息,请参见“问题...”中的“最佳做法”。我会帮助您解释表格中显示的十六进制是否正确。