首页 > 解决方案 > 在所有列中将字符集 Latin1 转换为 Utf-8

问题描述

我在 Latin1 有一家巨大的银行,我需要转换银行所有列的所有值。

搜索发现了一个手动执行此操作的命令。

UPDATE table SET column = CONVERT (cast (CONVERT (column USING latin1) AS BINARY) USING utf8);

但是银行有很多表和列,所以手动进行转换是不切实际的,你能帮我写一些脚本,把这个命令带到银行的所有列吗?

标签: mysqlphpmyadmincharacter-encodingmysql-workbench

解决方案


——首先让我们决定完整的情况是什么。

你用的是什么版本?如果 MySQL 5.7,考虑去 utf8mb4,这样你就可以处理 Emoji 和所有的中文。如果是 5.5 或 5.6,那也是可能的,但你可能会遇到一些问题。

http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases

情况 1: 这些列当前CHARACTER SET latin1 包含 latin1 编码的文本。然后对每个表执行此操作:

ALTER TABLE t CONVERT TO CHARACTER SET utf8;

情况 2: 这些列当前是CHARACTER SET latin1 ,但其中包含 utf8 编码的字符。这导致了 Mojibake 或无声的“双重编码”。该修复程序需要为每列进行一对更改:

情况 3(双重编码):然后,只有这样,才需要:

UPDATE tbl SET col = CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4);

更多讨论

CHARACTER SET latin1,但其中包含 utf8 字节;在修复 charset 时不理会字节:首先,假设您对 tbl.col 有以下声明:

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 作为中间定义。(这是“2 步 ALTER,如其他地方所述。)(确保其他规范保持相同 - VARCHAR、NOT NULL 等)

这种情况下??

为了确定您的情况,请通过以下方式提供当前数据的小样本:

 SELECT HEX(col), col FROM t WHERE ...

示例:如果colhas é,并且 HEX 是E9-- 那就是 latin1。如果 Hex 是C3A9,则 utf8 不正确地存储到 latin1 中。十六进制C383C2A9表示“双重编码”。

生成 ALTER

ALTERs可以在此处找到有关如何生成的提示。(这不完全是您所需要的,但很接近。)


推荐阅读