2016-11-10 58 views
0

我有一個MySQL數據庫託管在某些提供程序中。在過去的3年裏,一切都運行正常,但從昨天開始,所有特殊字符現在都顯示爲無效字符。例如:特殊字符上的MySQL錯誤

'sugestão' now shows as 'sugestão' 

我並沒有在數據庫中的任何改變主機公司聲稱他們不能無能爲力。而最爲陌生的是,新的內含物不會受到這個問題的影響,只有昨天之前包含的數據。

我知道主機後端發生了一些事情,但他們拒絕承認,因爲他們聲稱他們沒有任何日誌來證明我沒有更改數據庫字符集或排序規則。但當然,我知道我沒有這樣做,這是一個運行了3年的應用程序,從來沒有這個問題。

所以我自己解決問題,手動更新所有這些問題的列,在每個表中。有沒有辦法在MySql Workbench本身內部更快地完成此操作,而不是創建一些應用程序?

例如,我有一個名爲'CRM'的表。下面是一些示例結果集:

select * from crm; 
cr_date  cr_history 
2016-07-11 Quer sugestão 
2016-07-11 País de destino : Canadá 

下面是這個結果集的問題之前是什麼樣子,我需要如何解決它回來再看看:

select * from crm; 
cr_date  cr_history 
2016-07-11 Quer sugestão 
2016-07-11 País de destino : Canadá 

有沒有辦法做一個更新查詢以將列中的所有'ã'字符串更改爲'ã',保持列內容的其餘部分不變?

像這樣的東西:將字段中的所有ocurencies o'ã'替換爲'ã'。像PHP的str_replace,但直接在Mysql中。

只需添加更多的信息,它是由一個PHP應用程序訪問數據庫,但問題發生直接從MySQL Workbench中訪問數據庫,所以它不是一個PHP相關的問題。

在此先感謝!

+1

我的猜測是,當你連接到MySQL並依靠默認設置時,你不會在PHP中設置編碼。 –

+0

就像我說的,問題直接在MySQL Workbench中訪問數據庫。 – delphirules

+1

該函數被稱爲['replace'](http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_replace)。另一種方法:用你最喜歡的編輯器/工具做一個mysqldump,一個完整的文本替換和重新導入。 (您必須先將頁面取下,然後確保您的工具區分大小寫)。如果你有一箇舊的轉儲,你可以檢查(和比較當前轉儲)你的第一行,如'SET NAMES',字符集或mysql服務器版本,看看是否有變化。另一方面,它有時可能是您的主機配置頁面中的簡單開關。 – Solarflare

回答

2

當某些東西在ANSI(或其他非UTF)列中存儲UTF-8數據時,這是非常典型的(並且經常出現)結果。 PHP似乎特別容易出現這種類型的錯誤(我以前見過這種情況)。所以,當檢索數據時,它會在列的編碼中被解釋,而不是其真正的編碼 - 因此顯示錯誤。

你可以像這樣很容易看到這一點:

mysql> SELECT CAST(_latin1'müller' AS CHAR CHARACTER SET utf8); 
+---------------------------------------------------+ 
| CAST(_latin1'müller' AS CHAR CHARACTER SET utf8) | 
+---------------------------------------------------+ 
| müller           | 
+---------------------------------------------------+ 
1 row in set (0,00 sec) 

mysql> SELECT CAST('müller' AS CHAR CHARACTER SET utf8); 
+--------------------------------------------+ 
| CAST('müller' AS CHAR CHARACTER SET utf8) | 
+--------------------------------------------+ 
| müller          | 
+--------------------------------------------+ 
1 row in set (0,00 sec) 

你可以做的是設置正確的編碼(charset在(我的)SQL)該列。您可以使用ALTER TABLE命令,但這樣會進一步混淆現有值(它會嘗試再次以UTF-8重新編碼已編碼的UTF-8值)。所以更好的方法是:

  • 添加一個帶有UTF-8字符集+排序規則的新列。
  • 更新您的表並將新列的值設置爲舊列的值。這裏重要的是to cast舊列的字符集到它的真實值(UTF-8)。這不會轉換數據,只是將現有字節存儲在新列中,但這次使用正確的編碼。
  • 完成後,移除舊列並將新列重新命名爲舊名稱。

有了這個額外的列,你確保你不會丟失數據(備份仍然值得推薦),你可以放棄它,並在出現問題時重新開始。

+0

感謝您的建議。我不明白的是,爲什麼這個問題從哪裏出現;一切工作正常。主機公司聲稱他們沒有在他們的後端,或者我改變了我的應用程序的任何東西。 – delphirules