在 DB2 UDB 資料庫儲存多語系資料時,Unicode 常為唯一能適應完整資料範圍的編碼。DB2 可儲存處理 Unicode 資料,但排序功能僅限二進位排序與三種文化排序,且一個資料庫僅能有一種排序規則(建立時決定)。對需支援多語言的使用者與資料,此限制顯然棘手。
IBM 建立管理 Unicode 資料的函數庫 ICU (International Components for Unicode),為 C 與 Java 提供完整操作 Unicode 資料的函數,以無限制開源授權釋出,廣泛適用。ICU 實作標準 Unicode Collation Algorithm (UCA) 及眾多文化調整功能。將適當 ICU 函數組合成 UDF(使用者定義函數),即可讓 DB2 充分利用 ICU 排序支援(註:DB2 for Linux, UNIX, Windows 即用 ICU 庫實現三種文化排序)。
本文針對 DB2 V8 for Linux, UNIX, Windows,UDF 範例亦適用即將發布的 Viper,理論上可用於 DB2 V7 FP3+(未測試),或許適用 zSeries/iSeries(未測試、本文不討論)。
假設資料庫名為 SAMPLE,實際可用任意 Unicode 資料庫。判斷是否 Unicode 資料庫:
db2 get database configuration for sample
Database code page 須為 utf-8。無 Unicode 資料庫時可建立:
db2 create database sample using codeset utf-8 territory ca
sortkey-Linux-x86.zip 解壓至暫存目錄sortkey、libicui18n.so.34、libicuuc.so.34、libicudata.so.34 至 sqllib/functiondb2 connect to sample && db2 -tvf createfn.db2註:Linux 預建碼於 Red Hat Linux 7.2 用 gcc 2.96 編譯。
sortkey-Windows-32.zip 解壓sortkey.dll、icuin34.dll、icuuc34.dll、icudt34.dll 至 sqllib/functiondb2 connect to sample && db2 -tvf createfn.db2PATH;Windows 另需更新 LIB(指向 iculib)與 INCLUDE(指向 icuinclude)環境變數sortkey-source.zip 解壓;複製 sqllib/samples/c/bldrtn (Windows 為 bldrtn.bat) 至暫存目錄並編輯,編譯連結步驟加入 ICU 資訊ICU_C_FLAGS、ICU_L_FLAGS 加入編譯連結命令(清單 1)bldrtn sortkey 編譯 UDFsortkey (Windows 為 sortkey.dll) 至 sqllib/function,連線資料庫執行 DDL 編目注意:此法編譯 UDF 要求執行機器完整安裝 ICU。
清單 1. 修改的 Linux bldrtn 檔案
# If an embedded SQL program, precompile and bind it.
if [ -f $1".sqc" ]; then ./embprep $1 $2; fi
# ICU options
ICU_C_FLAGS="`icu-config --cppflags --cxxflags`"
ICU_L_FLAGS="`icu-config --ldflags`"
# Compile the program.
$CC $ICU_C_FLAGS $EXTRA_C_FLAGS -I$DB2PATH/include -c $1.c -D_REENTRANT
# Link the program and create a shared library
$CC $ICU_L_FLAGS $LINK_FLAGS -o $1 $1.o $EXTRA_LFLAG -L$DB2PATH/$LIB -ldb2 -lpthread
清單 2. 修改的 Windows bldrtn.bat 檔案
:link_step
rem Link the program.
link -debug -out:%1.dll -dll %1.obj db2api.lib icudt.lib icuuc.lib icuin.lib -def:%1.def
>>--SORTKEY--(--string-expression--,--collation-name--)--><
UDF 結構描述為 ICU。若 ICU 在 SQL PATH 中,無需顯式限定。SORTKEY 回傳 VARCHAR(1200) FOR BIT DATA 字串,代表指定 collation-name 中 string-expression 的排序鍵。長度超過 1200 位元組時截斷並回傳警告 (SQLSTATE 01HKY)。結果可為 NULL,任一參數為 NULL 則結果為 NULL。
可對兩字串的 SORTKEY 結果做二進位比較,判斷其在指定排序規則中的次序。比較需來自相同 collation-name 的結果始有意義。
必須從 Unicode 資料庫呼叫 SORTKEY,否則報錯 (SQLSTATE SKUTF)。
example.db2 含 UTF-8 編碼字元。理想從 Unicode shell 執行範例。非 Unicode shell 時,SORTKEY_GERMAN1、SORTKEY_GERMAN2 表會含錯誤資料,範例 4 失敗。允許非 Unicode shell 執行可設 DB2CODEPAGE=1208(DB2 客戶端以 UTF-8 處理資料),重音字元無法正確顯示但範例可正確執行:
db2 terminate
db2set DB2CODEPAGE=1208
db2 connect to sample
db2 -tf example.db2
執行後可恢復:db2 terminate && db2set DB2CODEPAGE=。範例使用的表、資料、查詢在 example.db2 中,連線資料庫時用 db2 -tf example.db2 執行。