前一个是在 CSV 文件是-encodedLOAD DATA INFILE
的假设下运行的。latin1
在此导入期间,多字节字符被解释为两个单个字符,然后使用 utf-8(再次)进行编码。
这种双重编码会产生异常,例如ñ
而不是ñ
.
如何更正这些字符串?
前一个是在 CSV 文件是-encodedLOAD DATA INFILE
的假设下运行的。latin1
在此导入期间,多字节字符被解释为两个单个字符,然后使用 utf-8(再次)进行编码。
这种双重编码会产生异常,例如ñ
而不是ñ
.
如何更正这些字符串?
以下 MySQL 函数将在双重编码后返回正确的 utf8 字符串:
CONVERT(CAST(CONVERT(field USING latin1) AS BINARY) USING utf8)
它可以与UPDATE
语句一起使用来更正字段:
UPDATE tablename SET
field = CONVERT(CAST(CONVERT(field USING latin1) AS BINARY) USING utf8);
上面的答案适用于我的一些数据,但运行后导致很多 NULL 列。我的想法是,如果转换不成功,它会返回 null。为了避免这种情况,我加了一张小支票。
UPDATE
tbl
SET
col =
CASE
WHEN CONVERT(CAST(CONVERT(col USING latin1) AS BINARY) USING utf8) IS NULL THEN col
ELSE CONVERT(CAST(CONVERT(col USING latin1) AS BINARY) USING utf8)
END
我也遇到了这个问题,这里是 Oracle 的解决方案:
update tablename t set t.colname = convert(t.colname, 'WE8ISO8859P1', 'UTF8') where t.colname like '%Ã%'
另一个用于 Java:
public static String fixDoubleEncoded(String text) {
final Pattern pattern = Pattern.compile("^.*Ã[^0-9a-zA-Z\\ \t].*$");
try {
while (pattern.matcher(text).matches())
text = new String(text.getBytes("iso-8859-1"), "utf-8");
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return text;
}
那么使用“utf8mb4”而不是“utf8”非常重要,因为mysql会在一个无法识别的字符之后删除所有数据。所以更安全的方法是;
UPDATE tablename SET
field = CONVERT(CAST(CONVERT(field USING latin1) AS BINARY) USING utf8mb4);
小心这个。