Sql-Server

從 CSV 文件導入字元轉換問題

  • July 24, 2019

在載入 CSV 文件後,有各種單詞被錯誤地“寫入”到數據庫中。

一些例子:

  • Diã¡ria應該Diária
  • Crã©dito應該Crédito
  • Ligaã§ãµes應該Ligações
  • Usuã¡rio應該Usuário
  • Nãºmeros應該Números

有沒有辦法將符號翻譯成正確的字元?

我已經做了幾個不同的測試collationsfunctions可以搜尋網際網路,但沒有成功。

有各種單詞被錯誤地“寫入”到數據庫中。

不,字元被錯誤地讀取。它們的書寫正確。或者,另一種看待這個問題的方式是:字元被錯誤地寫入數據文件。無論哪種方式,SQL Server 都在做它被要求做的事情。

這是一個簡單的編碼問題。數據最初以 UTF-8 格式導出,但隨後將該 UTF-8 編碼文件讀入 SQL Server,就好像它是使用程式碼頁 1252 的擴展 ASCII 文件一樣。有三個線索表明這是問題所在:

  1. 大多數字元都正確通過。那些不是重音字元。
  2. 不正確的字元以兩個字元而不是一個字元的形式出現。
  3. 您提到導出到“ASCII”文件是有效的。

UTF-8 是一種多字節編碼:它使用不同數量的字節,具體取決於被編碼的字元。前 128 個程式碼點 (U+0000 - U+007F),包含美國英語字母表,都使用 1 個字節。高於該範圍的程式碼點佔用 2 - 4 個字節。這就是為什麼某些字元在系統之間按預期傳輸的原因:(N大寫拉丁語“N”)在 UTF-8 和程式碼頁 1252 中是0x4E(實際上,它在 SQL Server 支持的所有 8 位程式碼頁中都是0x4E)。這也是 UTF-8 如此受歡迎的原因之一。但是,重音字元在 UTF-8 中不是 1 個字節:

  • ( áU+00E1 ) 在 UTF-8 中被編碼為兩個字節:0xC30xA1。當這兩個字節被期望程式碼頁 1252 的東西讀取時,它們被解釋為Ã(程式碼頁 1252 上的0xC3)和¡(程式碼頁 1252 上的0xA1)。然後,無論是您還是您的導入過程,都將小寫Ã(可能是因為它位於單詞的中間),這就是您最終得到的結果:Usuã¡rio.
  • ( úU+00FA ) 在 UTF-8 中編碼為兩個字節:0xC30xBA。當這兩個字節被期望程式碼頁 1252 的東西讀取時,它們被解釋為Ã(程式碼頁 1252 上的0xC3)和º(程式碼頁 1252 上的0xBA)。然後,無論是您還是您的導入過程,都將小寫Ã(可能是因為它位於單詞的中間),這就是您最終得到的結果:Nãºmero.

您的選擇是:

  1. 使用程式碼頁 1252(導出時)將文件編碼為(擴展)ASCII,並且不要更改將其讀入 SQL Server 的方式。(聽起來你已經這樣做了)。
  2. 繼續使用 UTF-8 編碼導出文件,但通過指定文件被編碼為 UTF-8 來更改文件被讀入 SQL Server 的方式。請注意,對於使用BCP.exeBULK INSERT或的任何人OPENROWSET(BULK...),此選項僅從 SQL Server 2016 開始可用。要使用的程式碼頁是65001(通常表示帶有字節順序標記的 UTF-8 ,但我不確定 SQL Server在這些情況下需要字節順序標記)。

引用自:https://dba.stackexchange.com/questions/204887