微軟BI 之SSIS 系列 - ETL 轉換時關於 Code Page (1252 and 936) 轉換錯誤的緣由和解決方法

開篇介紹

最近常常碰到在 ETL 練習中出現這種轉換失敗的問題,試了多種方式,一樣的代碼一樣的源結構和表結構可是一直不能成功執行,包報錯。通常有這麼幾種錯誤:html

Error at DST_LOAD_DATA_FROM_FILE [OLE_DST_EMPLOYEE[109]]: The column "FirstName" cannot be processed because more than one code page (1252 and 936) are specified for it.數據庫

或者就是ide

[OLE DB Destination [2]] Error: SSIS Error Code DTS_E_OLEDBERROR.  An OLE DB error has occurred. Error code: 0x80004005.測試

An OLE DB record is available.  Source: "Microsoft SQL Server Native Client 11.0"  Hresult: 0x80004005  Description:spa

"OLE DB provider 'STREAM' for linked server '(null)' returned invalid data for column '[!BulkInsert] .FirstName'.".code

那麼這些問題是如何形成的呢?server

不一致的字符集

這些錯誤與兩方面因素有關,一方面是數據源,一方面是目標表。htm

在咱們的測試案例文件中,源案例文件中包含有一些西歐字符,西歐拉丁字符集就是 1252。而咱們有些測試環境下目標數據庫中的字符集是 GBK - 表示簡體中文,那麼這種轉換要麼就是轉換失敗,要麼就是轉換成功可是顯示爲亂碼。對象

下圖是咱們的源文件中的西歐拉丁字符,這種字符是沒法存儲在 GBK 字符集格式下的數據庫中的,強行存儲就是一個亂碼。blog

右鍵查看咱們的目標表,若是它的 Collation 是 SQL_Latin1_General_CP1_CI_AS 的話這種文件數據加到對應的表中是沒有任何問題的。

可是若是是這樣的 Collation 就會出現錯誤。

錯誤還原

建立數據流 Data Flow Task 並設置文件數據源和目標表對象(Collation = Chinese_PRC_CI_AS),文件鏈接管理器中的 Locale 是英語,Code Page 是 1252。

已經能夠看到報錯信息了:

The column "FirstName" cannot be processed because more than one code page (1252 and 936) are specified....

若是強制執行,就會看到這種信息:

Error at DST_OAD_DATA_FROM_FILE [OLE_DST_EMPLOYEE[109]]: The column "FirstName" cannot be processed because more than one code page (1252 and 936) are specified for it.

Error at DST_LOAD_DATA_FROM_FILE [OLE_DST_EMPLOYEE[109]]: The column "FirstName" cannot be processed because more than one code page (1252 and 936) are specified for it.

錯誤的緣由在於數據流 DST_LOAD_DATA_FROM_FILE 中的數據流控件 OLE_DST_EMPOYEE 即 OLE DB Destination 目標控件中的列有多於一個以上的 Code Page 1252 和 936。 很顯然 1252 指的是自動識別到的文件數據源中的字符集是拉丁西歐字符 1252, 而 936 則表示咱們目標表中的字符格式。目標控件不知道如何選擇哪種字符集來處理,不統一就沒法處理。

咱們將文件連接管理器中的 Locale 改爲簡體中文 Chinese Simplified, Code Page 自動變爲 936 GBK 類型。

這時的包編輯經過。

但執行再次報錯。

錯誤緣由:

[OLE DB Destination [2]] Error: SSIS Error Code DTS_E_OLEDBERROR.  An OLE DB error has occurred. Error code: 0x80004005.

An OLE DB record is available.  Source: "Microsoft SQL Server Native Client 11.0"  Hresult: 0x80004005  Description:

"OLE DB provider 'STREAM' for linked server '(null)' returned invalid data for column '[!BulkInsert] .FirstName'.".

注意到錯誤最後有一個 Bulk Insert 的插入方式,提示了咱們在 OLE_DST_EMPLOYEE 控件中使用的是 Bulk Insert 的插入方式。Bulk Insert 又稱之爲數據拷貝,速度和效率都很高,可是在 Bulk Insert 的過程當中是不考慮字符轉換的,若是字符不能完成相應的轉換,一旦沒法存儲就會發生報錯。

能夠想想,咱們的源文件中的拉丁西歐字符是沒法轉換成對應的 GBK 簡體中文的,因此在 OLE_DST_EMPLOYEE 中必定採用了 Bulk Insert 的方式,而且因爲沒有字符轉換這一過程,GBK 的數據類型是沒法保存這種西歐拉丁字符的。

爲何是 Bulk Insert 的方式,能夠看看 OLE_DST_EMPLOYEE 就明白了,這裏採用的是 Table or View - Fast Load 的模式。 Fast Load 只因此效率高,是由於它採用的就是 Bulk Insert 這種方式。

這也就是不少同窗將 Table or view - Fast Load 改成 Table or view 就不會發生執行失敗的緣由。由於在普通的 Table or view 的加載模式下,這種字符類型會強制的變爲 GBK 可接受的數據格式。

執行成功了。

可是到數據庫中查查就會發現這個西歐字符其實是沒有轉換成功的,變成了亂碼。而這個亂碼是不受咱們控制的,由於目標數據庫,表的 Collation 就是 GBK 格式。

 

Code Page 的相關文章

什麼是 Code Page  

更多 BI 文章請參看 BI 系列隨筆列表 (SSIS, SSRS, SSAS, MDX, SQL Server)  若是以爲這篇文章看了對您有幫助,請幫助推薦,以方便他人在 BIWORK 博客推薦欄中快速看到這些文章。

相關文章
相關標籤/搜索