2

MySQL 使用函数 HEX() 将字符序列转换为十六进制表示。唯一的问题是它假设每个字符都是两个字节。这在大多数情况下都很好,但使用 utf-8 有时字符跨越超过 2 个字节。

例如。0xEFBFBD 是用于表示编码错误的三字节字符。当我在 utf8 编码表中一个接一个地在 DB 中有两个这样的字符时(总共 6 个字节),我尝试从表中选择十六进制(col1)...,结果为 0xC3AFC2BFC2BD 而不是 0xEFBFBD。如果我使用 php 中的查询选择它,然后在 php 中转换为十六进制,它会以正确的格式出现。

最好的功能是 MySql,它可以解码正确的多字节 UTF8。我很惊讶它似乎不存在,并且想知道其他人是否也发现了这种情况以及可能的解决方法。

我在 MySql 中找到的最接近答案的是: http: //forums.mysql.com/read.php?103,375304,375660

但这个建议并没有真正帮助。如果没有人想到任何想法,我稍后会发布一个测试用例。

4

1 回答 1

2

HEX函数返回实际存储的字节;请记住,MySQL 很乐意存储混合的字符编码。如果您为每个字符获取两个字节,则您的值必须用ucs2orutf16编码。要检查编码,您可以使用该CHARSET功能

在这种特殊情况下,该列似乎包含以 UTF-16 编码的 쎯슿슽 (U+C3AF U+C2BF U+C2BD)。一定有其他问题让你相信 �� (U+FFFD U+FFFD) 是存储值。也许您的 PHP 程序正在使用ucs2utf16作为连接字符集,然后将获得的文本视为 UTF-8?


更新:要获得字符串的 UTF-8 编码的十六进制表示——任何字符串,任何编码*)——,请使用HEX(CONVERT(string USING utf8)). 例如:

set @unknown = char(0xFFFD using ucs2);        -- stored bytes: \xFF \xFD
select hex(convert(@unknown using utf8));      -- output: EFBFBD

*) 除了没有编码转换的二进制字符串

于 2012-07-15T11:33:21.590 回答