DB2中建立漢字拼音首字母的SQL函式

iSQlServer發表於2009-11-05

需求

  有些時候我們會有這樣的需求,要求使用字母從a至z對一組資料進行索引,如果資料的格式全部是半形的英文則很容易實現,但若是對一組中文資料進行索引則會引起一點小的麻煩,資料在錄入db2資料庫的時候可能並沒有指定一個索引字母,這就要求應用程式可以自動生成用於索引的資訊。

  一般對於中文資料的索引,採用片語的首漢字拼音的首字母,例如:

片語 索引字母
--- -----
熊貓 x
白暨豚 b
藏野驢 z

  在DB2中並沒有提供相應的函式可以取得漢字拼音的首字母,我們可以利用資料庫針對中文字符集的排序功能建立一個這樣的函式。

  工作原理

  我們知道在使用中文字符集的資料庫中,當你對一列中文資料使用order by 排序時,排序的結果正是按照每行記錄第一個漢字的拼音首字母進行排列的,那麼我們需要想辦法取得這個字母。

  但是資料庫內部是如何做到這一點的呢?以中文字符集GBK為例,讓我們檢視一下GBK字符集的內碼錶,我們僅摘出一段:

0 1 2 3 4 5 6 7 8 9 A B C D E F 
B040 癅 癆 癇 癈 癉 癊 癋 癎 癏 癐 癑 癒 癓 癕 癗 癘
B050 癙 癚 癛 癝 癟 癠 痴 癢 癤 癥 癦 癧 癨 癩 癪 癬
B060 癭 癮 癰 癱 癲 癳 癴 癵 癶 癷 癹 発 發 癿 皀 皁
B070 皃 皅 皉 皊 皌 皍 皏 皐 皒 皔 皕 皗 皘 皚 皛
B080 皜 皝 皞 皟 皠 皡 皢 皣 皥 皦 皧 皨 皩 皪 皫 皬
B090 皭 皯 皰 皳 皵 皶 皷 皸 皹 皺 皻 皼 皽 皾 盀 盁
B0A0 盃 啊 阿 埃 挨 哎 唉 哀 皚 癌 藹 矮 艾 礙 愛 隘
B0B0 鞍 氨 安 俺 按 暗 岸 胺 案 骯 昂 盎 凹 敖 熬 翱
B0C0 襖 傲 奧 懊 澳 芭 捌 扒 叭 吧 笆 八 疤 巴 拔 跋
B0D0 靶 把 耙 壩 霸 罷 爸 白 柏 百 擺 佰 敗 拜 稗 斑
B0E0 班 搬 扳 般 頒 板 版 扮 拌 伴 瓣 半 辦 絆 邦 幫
B0F0 梆 榜 膀 綁 棒 磅 蚌 鎊 傍 謗 苞 胞 包 褒 剝

  可以看到從B0A0-1 開始,至B0C0-5,是拼音A開頭的漢字,恰好是按照拼音字母的先後順序排列,並且把音調的因素也考慮進去了,由此,可以推斷出,資料庫在GBk編碼的資料庫中對漢字進行排序,即是依照字元內碼錶的編碼進行的。

  我們把B0C0-5 位置的漢字記錄下來,即“澳”字,這是以“a”拼音開頭在內碼錶中排列在最後的漢字,用同樣的方法,我們找出所有以拼音從b至z開頭,在內碼錶中排列在最後的漢字,與26個字母的對應關係如下:

'澳' a
'怖' b
'錯' c
'墮' d
'貳' e
'咐' f
'過' g
'禍' h
i
'駿' j
'闊' k
'絡' l
'穆' m
'諾' n
'漚' o
'瀑' p
'群' q
'弱' r
'所' s
'唾' t
u
v
'誤' w
'迅' x
'孕' y
'座 z

  注:沒有以'i','u','v'開頭的漢語拼音。

  現在假若我們拿出任何一個漢字,放在我們挑選出的這些漢字中間,利用資料庫進行一次使用GBK字符集的排序,我們便能夠根據這個漢字排列的相對位置得到其拼音首字母。

  利用sql語句生成一組上述漢字的結果集,我們將'i','u','v' 三個空缺漢字的位置補上了上一個拼音的漢字,

select t1.strChn 
from ( select '澳' strChn from sysibm.sysdummy1
union all
select '怖' strChn from sysibm.sysdummy1
union all
select '錯' strChn from sysibm.sysdummy1
union all
select '墮' strChn from sysibm.sysdummy1
union all
select '貳' strChn from sysibm.sysdummy1
union all
select '咐' strChn from sysibm.sysdummy1
union all
select '過' strChn from sysibm.sysdummy1
union all
select '禍' strChn from sysibm.sysdummy1
union all
select '禍' strChn from sysibm.sysdummy1
union all
select '駿' strChn from sysibm.sysdummy1
union all
select '闊' strChn from sysibm.sysdummy1
union all
select '絡' strChn from sysibm.sysdummy1
union all
select '穆' strChn from sysibm.sysdummy1
union all
select '諾' strChn from sysibm.sysdummy1
union all
select '漚' strChn from sysibm.sysdummy1
union all
select '瀑' strChn from sysibm.sysdummy1
union all
select '群' strChn from sysibm.sysdummy1
union all
select '弱' strChn from sysibm.sysdummy1
union all
select '所' strChn from sysibm.sysdummy1
union all
select '唾' strChn from sysibm.sysdummy1
union all
select '唾' strChn from sysibm.sysdummy1
union all
select '唾' strChn from sysibm.sysdummy1
union all
select '誤' strChn from sysibm.sysdummy1
union all
select '迅' strChn from sysibm.sysdummy1
union all
select '孕' strChn from sysibm.sysdummy1
union all
select '座' strChn from sysibm.sysdummy1
) as
t1

  實現

  接下來很方便的就可以寫出這個函式的具體實現,在實現的程式碼中,我們又加入了針對英文字母的處理,函式編譯後,可通過如下方式呼叫:

select getIndex( '索' ) index from dual;

index
------
f

  實際使用中,應注意建立資料庫時字符集引數的設定,應使用GBK字符集。

  應用以下命令檢視已建立資料庫的字符集:

DB2 connect to db_name user user_name using passWord
db2 get db cfg | grep -i 'code set'

  此引數在資料庫建立之後不能修改。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-618201/,如需轉載,請註明出處,否則將追究法律責任。

相關文章