1. 程式人生 > >DB2 中LOAD和IMPORT的Codepage轉換

DB2 中LOAD和IMPORT的Codepage轉換

在 DB2 中,LOAD 與 IMPORT 作為重要的匯入資料的工具,有著很重要的作用。理想情況下,為了獲得最佳效能,應用程式與從該應用程式呼叫的語句始終應使用相同的內碼表。在一些場景中,我們需要匯入一些和資料庫本身的 codepage 不一致的資料,這個時候就需要 codepage 轉換了。DB2 產品支援內碼表轉換,從而允許應用程式和資料庫使用不同的內碼表。那麼什麼是 codepage ? DB2 支援那些 codepage 轉化? 如何進行 codepage 轉換呢?

  Codepage 介紹

  計算機處理文字時,把一門語言中每個字元都賦以特定的值,這種字元與數值的對照表就叫 codepage( 內碼表 ) 。例如 ASCII 就是把英文字母表和一些控制字元對映到一些特定的數值上去。

  DB2 支援的 codepage 列表

  關於 DB2 支援的 codepage 可以在 DB2 資訊中心中檢視:

  http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.JSP?topic=/com.ibm.db2.luw.admin.nls.doc/doc/r0004565.html

  在表中,每個 codepage 都有相對應的組,地域程式碼,程式碼集等。如果兩個 codepage 屬於同一個組,則它們可以互相轉換,否則不可以互相轉換。值得注意的是單位元組(S)組可以轉換成中性(N)組,雙位元組(D)組也可以轉換為中性(N)組。但是 N 組不一定能轉成 S 組,N 組也不一定成轉成 D 組。

  製造不同 CODEPAGE 資料的方式

  製造不同 codepage 資料的方法有很多種。以下列出 4 種:

  1. 使用 db2 export。DB2 本身 EXPORT 支援匯出各種不同 codepage 的 DEL 格式的檔案,例如匯出 codepage 為 819 和 1386 的檔案,如清單 1 所示。

清單 1. 匯出 codepage 為 819 和 1386 的檔案

 db2 "export to data819.del of del modified by codepage=819 
 select * from tab1" 
 
 db2 "export to data1386.del of del modified by codepage=1386 
 select * from tab1" 

  注意 export 不能直接匯出 asc 格式的檔案。

  2. 使用 UltraEdit 來編輯,先得到各種不同 codepage 資料的十六進位制程式碼(可以從網上搜索或者 GVT 網站上查取),然後編輯儲存就可以了。

  例如: “你” 在 GBK(1386) 中是 X ’ C4E3 ’ , 在 UTF-8(1208)中是 X ’ E4BDA0 ’

圖 1. 編輯‘你’的 GBK 程式碼
論 LOAD 與 IMPORT 中的 codepage 轉換

  3. 使用 Windows 作業系統下的 Microsoft Word 來製作資料,方式如下

  設定 –〉控制面板—〉區域和語言選項,設定你需要的語言,然後可以使用 WORD 來另存為純文字,選擇其它編碼來指定其編碼。

  4. 使用 vi 來設定 fileencoding 來達到目的

  例如準備 codepage 為 1208 的資料:

 set fileencoding=utf-8 

圖 2. 設定 fileencoding
論 LOAD 與 IMPORT 中的 codepage 轉換

  提示:準備數字和字母這些比較方便,但是準備中文,日文等就不是很方便了。建議使用 UltraEdit 來準備這些諸如中文,日文語言的 codepage。

  LOAD 與 IMPORT 不同轉換方式

  預設情況下,LOAD 認為輸入檔案是用資料庫內碼表編碼的,直接將檔案轉化為資料庫 codepage 編碼。如果輸入檔案不是以資料庫 codepage 編碼的,可以通過 codepage 修飾符來匯入正確檔案。而預設情況下 DB2 IMPORT 實用程式認為輸入檔案中的資料是用當前系統的內碼表編碼的。當將資料檔案匯入到資料庫時,DB2 會自動將資料檔案從當前系統內碼表轉換成資料庫內碼表。如果輸入檔案不是當前系統的內碼表編碼的。也可以通過 codepage 修飾符來輕鬆匯入正確檔案。

  所以一般來說,LOAD 直接把源資料的 codepage 轉化為資料庫的 codepage,而 IMPORT 則先將源資料的 codepage 轉換為應用程式的 codepage,然後將應用程式的 codepage 再轉換為資料庫的 codepage。

  LOAD 例項分析

  這些例子都是在 DB2 V97 中實現的,以下例項用的是同一個資料庫 db1386, 兩個資料檔案 data1386.del,data1208.del。

  data1386.del 和 data1208.del 包含同樣的資料第一列為 1,第二列為你,第三列為繜。但是編碼方式不同。data1386.del 以 codepage 1386 編碼,而 data1208 以 codepage 1208 編碼。

字元 GBK(1386) 程式碼點 UTF-8(1208) 程式碼點
X'C4E3' X'E4BDA0'
X'BF9F' X' E 7B99C'

  Linux 上當前系統內碼表可以通過 db2set db2codepage 來設定。另外需要 db2 terminate,使設定生效。

  db codepage 是建 DB 時由 codeset,territory 決定的。例如:

 db2 create db db1386 using codeset GBK territory CN 

  可以通過以下命令檢視 db 的 codepage。

 db2 get db cfg for dbname |grep 'Database code page' 

  資料 codepage 和 db codepage 一致時的 LOAD

  預設情況下 LOAD 認為資料 codepage 和 db codepage 一致,在這個例子中,匯入成功。

清單 2. LOAD 清單 1

 db2 create db db1386 using codeset GBK territory CN 
 db2set db2codepage=1386 
 db2 terminate 
 db2 connect to db1386 
 db2 "create table t1(a int, b varchar(7),c varchar(10))" 
 db2 load from data1386.del of del replace into t1 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 3 所示。

圖 3. 查詢結果 1
論 LOAD 與 IMPORT 中的 codepage 轉換

  資料 codepage 和 db codepage 不一致時的 LOAD

  這個例子屬於不正確的 LOAD,沒有做 codepage 轉換,data1208.del 被當成 db codepage 編碼存進了 db。

清單 3. LOAD 清單 2

 db2set db2codepage=1386 
 db2 terminate 
 db2 connect to db1386 
 db2 load from data1208.del of del replace into t1 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 4 所示。

圖 4. 查詢結果 2
論 LOAD 與 IMPORT 中的 codepage 轉換

  LOAD 時資料 codepage 不會轉成應用程式的 codepage

  data1208.del 不會轉成應用程式的 codepage,而是直接當成 db codepage 編碼存進 db。

清單 4. LOAD 清單 3

 db2set db2codepage=1208 
 db2 terminate 
 db2 connect to db1386 
 db2 load from data1208.del of del replace into t1  
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 5 所示。

圖 5. 查詢結果 3
論 LOAD 與 IMPORT 中的 codepage 轉換

  資料 codepage 和 db codepage 不一致時正確的 LOAD

  在這種情況下正確的 load,資料的 codepage 和 modified by codepage 一致,如清單 5 所示。

清單 5. LOAD 清單 4

 db2set db2codepage=1208 
 db2 terminate 
 db2 connect to db1386 
 db2 load from data1208.del of del modified by codepage=1208 
 replace into t1 
 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 6 所示。

圖 6. 查詢結果 4
論 LOAD 與 IMPORT 中的 codepage 轉換

  LMPORT 例項分析

  以下例子所用資料同上面 load 例項資料。

  資料 codepage 和應用程式 codepage, db codepage 一致時的 IMPORT

  預設情況下認為應用程式 codepage 就是資料的 codepage。

清單 6. IMPORT 清單 1

 db2set db2codepage=1386 
 db2 terminate 
 db2 connect to db1386 
 db2 import from data1386.del of del replace into t1 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 7 所示。

圖 7. 查詢結果 5
論 LOAD 與 IMPORT 中的 codepage 轉換

  資料 codepage 和應用程式 codepage 一致 , 但和 db codepage 不一致時的 IMPORT

  預設情況下認為應用程式 codepage 就是資料的 codepage,可以正確的匯入。

清單 7. IMPORT 清單 2

 db2set db2codepage=1208 
 db2 terminate 
 db2 connect to db1386 
 db2 import from data1208.del of del replace into t1 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 8 所示。

圖 8. 查詢結果 6
論 LOAD 與 IMPORT 中的 codepage 轉換

  資料 codepage 和應用程式 codepage 不一致時利用 modified by codepage 成功實現 import 的 codepage 轉換

清單 8. IMPORT 清單 3

 db2set db2codepage=1386 
 db2 terminate 
 db2 connect to db1386 
 db2 import from data1208.del of del modified by codepage=1208 
 replace into t1 
 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 9 所示。

圖 9. 查詢結果 7
論 LOAD 與 IMPORT 中的 codepage 轉換

  資料 codepage 和應用程式 codepage 不一致時不正確的 import,沒有實現 codepage 轉換

  把 data1208.del 當成應用程式 codepage 1386 編碼的,資料庫 codepage 也是 1386,不進行 codepage 轉換。

清單 9. IMPORT 清單 4

 db2set db2codepage=1386 
 db2 terminate 
 db2 connect to db1386 
 db2 import from data1208.del of del replace into t1 
 db2 "select hex(b) as b ,hex(c) as c from t1" 

  結果如圖 10 所示。

圖 10. 查詢結果 8    
論 LOAD 與 IMPORT 中的 codepage 轉換

  結束語

  本文介紹了 LOAD,IMPORT 在不同情況下的 codepage 轉換,以便使使用者更好的理解 codepage 轉換。