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 Unable to convert MySQL datetime value to System.DateTime 解决方案
解决 Unable to convert MySQL date/time value to System.DateTime