MySQL Convert latin1 to utf8, cp1252 0x80-0x9F 错误

Posted

技术标签:

【中文标题】MySQL Convert latin1 to utf8, cp1252 0x80-0x9F 错误【英文标题】:MySQL Convert latin1 to utf8, cp1252 0x80-0x9F wrong 【发布时间】:2014-12-12 08:57:35 【问题描述】:

情况: latin1 数据库已转储为 latin1,通过 iconv 转换为 utf8 并恢复为 utf8_unicode_ci。

除了 cp1252 中的 0x80-0x9F 之外,似乎每次转换都很顺利。通过将这些字符转换为 unicode,我没有完全理解 mysql 的含义:mysql:

latin1 是默认字符集。 MySQL 的 latin1 与 Windows cp1252 字符集相同。这意味着它与官方 ISO 8859-1 或 IANA(互联网数字分配机构)latin1 相同,除了 IANA latin1 将 0x80 和 0x9f 之间的代码点视为“未定义”,而 cp1252 以及 MySQL 的 latin1 分配字符对于那些职位。例如,0x80 是欧元符号。对于 cp1252 中的“未定义”条目,MySQL 将 0x81 转换为 Unicode 0x0081、0x8d 转换为 0x008d、0x8f 转换为 0x008f、0x90 转换为 0x0090、0x9d 转换为 0x009d。

例如,我的表格显示的是 0xC280 欧元,而不是 0x80 欧元。所以我想我是通过

误导转换
iconv -f latin1 -t utf8

相反,我应该由

转换
iconv -f cp1252 -t utf-8

正如我的测试所示。因为第二行做得对。

所以问题是,是否可以纠正那些坏字符,还是我必须转储整个数据库?

编辑: 是否可以转储坏数据库并通过转换

  --default-character-set=utf8
  iconv -c -f utf-8 -t latin1
  iconv -f latin1 -t utf-8 

然后再次插入数据库? iconv -c 会帮助我还是我会丢失信息?

编辑2: 似乎可以使用以下方法一一替换损坏的字符:

update history set note = replace(note,unhex('C280'),unhex('E282AC'));

这将成功地用正确的 3 字节 utf8 替换错误的 2 字节 glibberish。 当然,必须对每个 varchar/text 列以及范围内的每个损坏的字符都执行此操作 0x80-0x9F,不方便。 所以希望有人有更好的主意?

【问题讨论】:

【参考方案1】:

据我了解 iconv 命令是基于 C 的 iconv 函数: http://www.gnu.org/software/libiconv/documentation/libiconv-1.11/iconv.3.html

iconv 函数返回转换为 a 的字符数 此调用期间的不可逆方式;可逆转换不是 算了。如果发生错误,它会设置 errno 并返回 (size_t)(-1)。

因此您可以尝试反向转换,但根据文档,结果取决于第一次转换的返回码。当然你可以尝试二进制替换无效字符。

【讨论】:

糟糕的是我没有得到任何数字,因为我没有打印返回码:(你的二进制方法会是什么样子? 这可能会有所帮助***.com/questions/7760717/…

以上是关于MySQL Convert latin1 to utf8, cp1252 0x80-0x9F 错误的主要内容,如果未能解决你的问题,请参考以下文章

将 mysql 表从 latin1 转换为 utf8

mysql中latin1编码中文转utf8

MySQL Unable to convert MySQL datetime value to System.DateTime 解决方案

MySQL 常用脚本

MySQL 常用脚本

解决 Unable to convert MySQL date/time value to System.DateTime