Sql-Server
從 CSV 文件導入字元轉換問題
在載入 CSV 文件後,有各種單詞被錯誤地“寫入”到數據庫中。
一些例子:
Diã¡ria
應該Diária
Crã©dito
應該Crédito
Ligaã§ãµes
應該Ligações
Usuã¡rio
應該Usuário
Nãºmeros
應該Números
有沒有辦法將符號翻譯成正確的字元?
我已經做了幾個不同的測試
collations
,functions
可以搜尋網際網路,但沒有成功。
有各種單詞被錯誤地“寫入”到數據庫中。
不,字元被錯誤地讀取。它們的書寫正確。或者,另一種看待這個問題的方式是:字元被錯誤地寫入數據文件。無論哪種方式,SQL Server 都在做它被要求做的事情。
這是一個簡單的編碼問題。數據最初以 UTF-8 格式導出,但隨後將該 UTF-8 編碼文件讀入 SQL Server,就好像它是使用程式碼頁 1252 的擴展 ASCII 文件一樣。有三個線索表明這是問題所在:
- 大多數字元都正確通過。那些不是重音字元。
- 不正確的字元以兩個字元而不是一個字元的形式出現。
- 您提到導出到“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 中被編碼為兩個字節:0xC3和0xA1。當這兩個字節被期望程式碼頁 1252 的東西讀取時,它們被解釋為Ã
(程式碼頁 1252 上的0xC3)和¡
(程式碼頁 1252 上的0xA1)。然後,無論是您還是您的導入過程,都將小寫Ã
(可能是因為它位於單詞的中間),這就是您最終得到的結果:Usuã¡rio
.- (
ú
U+00FA ) 在 UTF-8 中編碼為兩個字節:0xC3和0xBA。當這兩個字節被期望程式碼頁 1252 的東西讀取時,它們被解釋為Ã
(程式碼頁 1252 上的0xC3)和º
(程式碼頁 1252 上的0xBA)。然後,無論是您還是您的導入過程,都將小寫Ã
(可能是因為它位於單詞的中間),這就是您最終得到的結果:Nãºmero
.您的選擇是:
- 使用程式碼頁 1252(導出時)將文件編碼為(擴展)ASCII,並且不要更改將其讀入 SQL Server 的方式。(聽起來你已經這樣做了)。
- 繼續使用 UTF-8 編碼導出文件,但通過指定文件被編碼為 UTF-8 來更改文件被讀入 SQL Server 的方式。請注意,對於使用BCP.exe、
BULK INSERT
或的任何人OPENROWSET(BULK...)
,此選項僅從 SQL Server 2016 開始可用。要使用的程式碼頁是65001
(通常表示帶有字節順序標記的 UTF-8 ,但我不確定 SQL Server在這些情況下需要字節順序標記)。