在全球化應用盛行的今天,資料庫必須妥善處理各國語言資料。DB2 9 引入字元語義的字串函數,徹底解決多位元組編碼(如 UTF-8)下的字元長度計算、搜尋定位與子字串擷取等難題。本文深入探討這些新函數的原理、用法與效能考量。
傳統 DB2 字串函數採用字節語義:單位元組字元集中長度等於位元組數,雙位元組字元集以雙位元組為單位。但多位元組編碼(UTF-8、UTF-16)下,單一字元可能佔 1–4 個位元組,導致 LENGTH、SUBSTR、LOCATE 等函數產生錯誤結果。
字元語義則以實際字元數計算長度。例如中文字串「測試」在 UTF-8 下佔 6 個位元組,但字元長度僅 2。DB2 9 引入 CHARACTER_LENGTH、SUBSTRING、POSITION 等函數,並支援 CODEUNITS16、CODEUNITS32、OCTETS 三種字串長度單位,讓開發者能精確控制字元邊界。
依指定單位回傳字串長度。範例:
VALUES CHARACTER_LENGTH(X'F09D849E', CODEUNITS32); -- 返回 1 (增補字元)
VALUES CHARACTER_LENGTH(X'F09D849E', CODEUNITS16); -- 返回 2 (代理對)
VALUES CHARACTER_LENGTH(X'F09D849E', OCTETS); -- 返回 4 (位元組數)
直接回傳位元組長度,等同 CHARACTER_LENGTH(..., OCTETS)。
新增選用 CODEUNITS 參數,搜尋起始位置與回傳位置皆依字元語義計算,避免多位元組字元導致的位置偏移。
支援 START、LENGTH、CODEUNITS 三參數,擷取子字串時不會拆分多位元組字元,確保資料完整性。
CODEUNITS16 計算會發出警告 (SQLSTATE 01517)。SUBSTRING 配合 CODEUNITS16 可能拆分代理對,建議改用 CODEUNITS32。新函數位於 SYSIBM 路徑,舊函數保留於 SYSFUN,預設路徑優先使用新函數。效能上,OCTETS 無需碼頁轉換,效率最高;CODEUNITS16/32 可能觸發 UTF-16/UTF-32 中間轉換,LOB 大物件影響較大,建議視情境選擇。
DB2 9 的字元型字串函數為多語言應用提供強健基礎,開發者應優先採用 CHARACTER_LENGTH、SUBSTRING、POSITION 等函數,將字元邊界邏輯下推至 SQL 層,簡化應用程式碼並提升正確性。