2015-05-22 33 views
0

我有一個數據庫用於存儲非英文字符的PHP應用程序,例如:ç ã éMySQL將錶轉換爲latin1不會將外部字符轉換爲正確的表示

以前,該數據庫已存儲並正確顯示這些字符,但在備份和恢復後,在他們的地方的某些字符被替換像çã組合時,它應該顯示Ç

顯然,這是一個備份或恢復charset疏忽,但我無法檢索以前的數據庫的好版本。

該轉儲文件是數據庫的所有剩餘部分,並且在文本編輯器中打開時,它也顯示組合012,代替çã

我試過將其中一個表從utf8_unicode_ci轉換爲latin1_swedish_ci,反之則無效。

ALTER TABLE test CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci; 
ALTER TABLE test CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci; 

我該如何解決這個問題。

謝謝。

注:utf8_decode從PHP能夠çã轉換爲ça,但我想,從源頭上解決這個問題。


更新:我能夠查詢受影響的表,並將它與下面的查詢返回正確的字符。

SELECT convert(cast(convert(field_name using latin1) as binary) using utf8) FROM affectedTable


更新2:

查詢波紋管能夠將字符轉換成其適當的UTF-8表示。

SELECT convert(cast(convert(field_name using latin1) as binary) using utf8) FROM affectedTable 

因此按照上述查詢的方法,如果您運行遵循三個查詢每個表的影響,應該將字符轉換爲UTF-8。

ALTER TABLE table CONVERT TO CHARACTER SET latin1; 
ALTER TABLE table CONVERT TO CHARACTER SET binary; 
ALTER TABLE table CONVERT TO CHARACTER SET utf8; 

那它,像çã字符將被轉換爲ça等。

這與MySQL 5.6.20 - 社區服務器在Windows上,它沒有與MySQL 5.5.42 - Linux上的社區服務器。也許有人知道這個交叉版本/操作系統解決方案。

回答

0

聲音就像表中的數據存儲爲latin1,但實際上是utf8。

在做「轉換成字符集」,它通常會嘗試基本字符從「latin1的」轉換爲「utf-8」

要更改類型不改變數據,你需要先列轉換爲一個二進制列,然後到最終的目標字符集,這應避免任何實際的字符轉換。

這這裏的文件中討論: https://dev.mysql.com/doc/refman/5.5/en/charset-conversion.html

+0

否。「CONVERT TO CHARACTER SET」僅用於將_zone _字符的charset和內容從latin1改爲utf8。 ''''意味着別的東西。 –

0

çã是變爲亂碼的çã

FROM ... 執行

SELECT山坳,HEX(COL)如果你得到六角C3A7C3A3çã,這是UTF8編碼。但是,如果您看到çãcol,則latin1正在爬行。如果該列聲明爲CHARACTER SET utf8,則該表格正常;連接中斷。連接時,您需要SET NAMES utf8或等效品。

如果你得到十六進制C383C2A7C383C2A3,你有「雙重編碼」,這是一個不同的解決方案。在完成所有ALTERs之後,如果你有這個爛攤子,我不會感到驚訝。

當您使用SET NAMES latin1將utf8字節寫入CHARACTER SET latin1列時,「2步ALTER」適用。症狀通常(但並不總是),您的çã顯示爲çã

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...; 
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...; 

(你3步改變是矯枉過正。)

當插入一個字符串,三件事情使​​插入的值是否是好還是壞的差異。

⚈ Data in client is _encoded_ latin1 versus utf8 
⚈ SET NAMES (or equivalent) is latin1 versus utf8 
⚈ The target column's CHARACTER SET is ascii vs latin1 vs utf8