2012-07-15 168 views
2

MySQL使用函數HEX()將HEX()轉換爲十六進制表示的字符序列。唯一的問題是它假定每個字符都是兩個字節。這在大多數情況下都很好,但對於utf-8,有時候字符跨越2個字節。Mysql HEX函數解碼多字節utf8

例如。 0xEFBFBD是用於表示編碼錯誤的三字節字符。當我在數據庫中有兩個這樣的字符(總共6個字節)時,在utf8編碼表中,我嘗試使用SELECT HEX(col1)FROM table ...,這會以0xC3AFC2BFC2BD而不是0xEFBFBD出現。如果我在php中使用查詢來選擇它,然後在PHP中將其轉換爲十六進制,則它會以正確的格式顯示。

什麼是最好的是一個函數是MySql,它可以解碼正確的多字節UTF8。我很驚訝,它似乎並不存在,並想知道是否有其他人也發現這種情況也是如此,可能的解決方法。

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

,但這一建議並沒有真正的幫助。如果沒有人有任何想法,我會在後期發佈測試用例。

回答

2

HEX函數返回實際存儲的字節;請記住,MySQL愉快地存儲了字符編碼的混合體。如果您爲每個字符獲取兩個字節,則您的值必須在ucs2 or utf16中編碼。要檢查編碼,您可以使用CHARSET function

看起來在這種特殊情況下,該列包含以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 

*)除了不具有編碼從

+0

其實轉換二進制字符串,這兩個表的字符集和php是UTF-8。 字符位於我已處理的原始文件中。 IE瀏覽器我在這個文件的原始數據中看過hexedit,它有兩個0xEFBFBD。所以這是正確存儲在數據庫中的0xEFBFBD。但是,如果我想在sql中編寫腳本來修復這些字符,在SQL中沒有多字節HEX解碼功能似乎很困難。我已經使用PHP解決了這個問題,但是如果有人知道對MySql HEX函數進行調整,可以正確解碼utf-8,我仍然對它感興趣。 – 2012-07-15 14:00:26

+0

請注意,如果我在php中使用查詢來選擇它,然後在php中將其轉換爲十六進制,則它正確表示爲0xEFBFBD。 – 2012-07-15 14:04:21

+0

然後,它看起來問題是與您插入數據的方式:該列不包含兩個U + FFFD字符。至於如何獲得字符串的UTF-8編碼的十六進制表示,請參閱更新。 – Joni 2012-07-16 06:48:51