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 程式碼
3. 使用 Windows 作業系統下的 Microsoft Word 來製作資料,方式如下
設定 –〉控制面板—〉區域和語言選項,設定你需要的語言,然後可以使用 WORD 來另存為純文字,選擇其它編碼來指定其編碼。
4. 使用 vi 來設定 fileencoding 來達到目的
例如準備 codepage 為 1208 的資料:
set fileencoding=utf-8
圖 2. 設定 fileencoding
提示:準備數字和字母這些比較方便,但是準備中文,日文等就不是很方便了。建議使用 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
資料 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 時資料 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
資料 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
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
資料 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
資料 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
資料 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 轉換,以便使使用者更好的理解 codepage 轉換。