获取汉字拼音首字母
上一篇 / 下一篇 2008-05-25 21:39:39 / 个人分类:ORACLE
在Oracle中获取汉字的拼音其实并不算复杂,这篇文章给出一个获取汉字拼音首字母的例子,并简单说明思路。
最近有个需求,要根据中文来获取汉语拼音的首字母。记得很早以前版主chensq和jlandzpa就给出过解决方法。不过这么简单的需求没有必要再去费劲找了,自己写一个就可以了。
介绍一下处理的思路,最简单的思路莫过于构造一个汉字库,手工为所有的汉字添加拼音,但是这种方法需要大量的人工录入工作,如果可以找到现成的字库倒是可以考虑。
那么能否利用Oracle提供的现有功能来解决。首先想到的是Oracle提供了SOUNDEX函数:
SQL> SELECT SOUNDEX('WORD') FROM DUAL;
SOUN
.o:EI9X z!t"d2Xw(cT0----ITPUB个人空间-k
Z'^p~/R
K
N
W630
SQL> SELECT SOUNDEX('词') FROM DUAL;
SITPUB个人空间3^V(c2B&W*VH~3e3cn
-
可惜的是,这个函数只对英文有效,对中文无效。看来只能使用其他的方法。
Oracle对各个国家不同的语言进行了本地化的开发,这其中就包括排序方式。查询了一下Oracle对于中文的排序支持,果然发现了对简体中文拼音的支持。
Oracle的SCHINESE_PINYIN_M排序方式可以支持中文的拼音排序,下面简单看一下使用这个中文拼音排序的例子:
SQL> WITH A AS
^*x$o#JQ#u0 2 (SELECT '获取汉字拼音首字母' W FROM DUAL)
k`Q } wt3j0 3 SELECT SUBSTR(W, ROWNUM, 1) FROM A
&w-AK xO ]V0 4 CONNECT BY ROWNUM <= (SELECT LENGTH(W) FROM A);
SUITPUB个人空间j}es cR1pH
--
N!g"R(CD#p'ME _U0获
,x1L.tIz8p[2t0取ITPUB个人空间dUT"g*Wh
汉ITPUB个人空间 {&U`1c,n5zJ{$^
字ITPUB个人空间
z9i:N}o5w b&Y
拼ITPUB个人空间gD3E%FN:?&aR#D
音
'X+UsO {X
rjZ0首ITPUB个人空间|+^.jUz Rw:c
字ITPUB个人空间S
EU1b `
母
已选择9行。
下面加上NLSSORT排序,并指定排序方法为SCHINESE_PINYIN_M:
SQL> WITH A AS
,|!pC:w'??K#RM0 2 (SELECT '获取汉字拼音首字母' W FROM DUAL)ITPUB个人空间 e n\"~T1PU$S:H5J
3 SELECT SUBSTR(W, ROWNUM, 1) FROM A ITPUB个人空间`0e Qb*v.t{X!H$K
4 CONNECT BY ROWNUM <= (SELECT LENGTH(W) FROM A)
E]L.H#B1x8q1_
}0 5 ORDER BY NLSSORT(SUBSTR(W, ROWNUM, 1), 'NLS_SORT=SCHINESE_PINYIN_M');
SU
V!A&qws6k5~
_ sY#GgC0--
8rz
H_&D0汉
{g(wvJ(AC s0获ITPUB个人空间*f;eIu8U~\&yb
母
%i;i`-@vZ9T0拼ITPUB个人空间#`3Fm#dP;Y!O
取ITPUB个人空间0e3o-i VDD,A`
首ITPUB个人空间&Jq:m+U`;W`UGV D
音
R+[7W9ZJ`0字
:}qCy;M6T0字
已选择9行。
利用Oracle的现成的排序方法,编写获取拼音首字母的函数就十分容易了,只需要找到每个首字母对应开头汉字和结尾汉字,根据这些边界汉字进行比较,就可以找到当前汉字的首字母信息。
SQL> WITH A AS
\1m+v.yJ+UZ9ui
P0 2 (
$F
{"DO'o.F;O
K0 3 SELECT ROWNUM RN, CHR(ROWNUM) C FROM DUAL CONNECT BY LEVEL <= 65535ITPUB个人空间s6F(W2H @
4 )
4i8l:w
e8r&nZ0 5 SELECT * FROM A WHERE LENGTHB(C) = 2
9pQSn-@m%g)c0 6 AND RN > 32768
.H|)eASE3}$~ M(~0 7 AND NLSSORT(C, 'NLS_SORT=SCHINESE_PINYIN_M') > NLSSORT('澳', 'NLS_SORT=SCHINESE_PINYIN_M')ITPUB个人空间!E$_&`C6C hK E
8 AND NLSSORT(C, 'NLS_SORT=SCHINESE_PINYIN_M') < NLSSORT('巴', 'NLS_SORT=SCHINESE_PINYIN_M')ITPUB个人空间0\X|2YW2w$bQ!vt:W
9 ORDER BY NLSSORT(C, 'NLS_SORT=SCHINESE_PINYIN_M');
RN CITPUB个人空间Q'nh}&e/~
---------- --ITPUB个人空间:zUT#M7WQ*J k
54931 謸ITPUB个人空间\:H%o^]4w
63179 鏊ITPUB个人空间l*e"X*D;n[A!M
62088 驁
"R4L+K.o8e e \&Y8~0 45259 八ITPUB个人空间+UUeWM"Z3^J
33172 仈
利用类似这样的方法,就可以分别找到每个首字母对应的字头和字尾。下面构建一个函数就十分容易了:
SQL> CREATE OR REPLACE FUNCTION F_PINYIN(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS
7LbTq`a8k^R0 2 V_COMPARE VARCHAR2(100);ITPUB个人空间`-Z|i C
\O5g
3 V_RETURN VARCHAR2(4000);ITPUB个人空间9fu+^Qb
4
G"gS6G4U aH;i'{
D0 5 FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 ASITPUB个人空间
M x Dn0w{'VY
6 BEGIN
;W(Cn&~]0 7 RETURN NLSSORT(P_WORD, 'NLS_SORT=SCHINESE_PINYIN_M');ITPUB个人空间fr.M,_#H4`)a
8 END;
|t U YrM-P:T$p0 9 BEGIN
Fa5n$V d Tz0 10
Sj~c0J.u q;t|0^/L0 11 FOR I IN 1..NVL(LENGTH(P_NAME), 0) LOOP
2b3g:w{,AB"wBP0 12 V_COMPARE := F_NLSSORT(SUBSTR(P_NAME, I, 1));
e%g'Y%DK&@0 13 IF V_COMPARE >= F_NLSSORT('吖') AND V_COMPARE <= F_NLSSORT('驁') THEN
'Y;F6vkv&D_ |.XV0 14 V_RETURN := V_RETURN || 'A';
'p@8[(D(xe*D0 15 ELSIF V_COMPARE >= F_NLSSORT('八') AND V_COMPARE <= F_NLSSORT('簿') THENITPUB个人空间'k%s)u$E)]"f1V$iz
16 V_RETURN := V_RETURN || 'B';ITPUB个人空间&I m-q?~!K;c
17 ELSIF V_COMPARE >= F_NLSSORT('嚓') AND V_COMPARE <= F_NLSSORT('錯') THEN
(a0uWrz6J!]0 18 V_RETURN := V_RETURN || 'C';ITPUB个人空间7k3Z2y8X~)es*W
19 ELSIF V_COMPARE >= F_NLSSORT('咑') AND V_COMPARE <= F_NLSSORT('鵽') THEN
_SHrOo(kX/f0 20 V_RETURN := V_RETURN || 'D';
3LSdkGr.X0 21 ELSIF V_COMPARE >= F_NLSSORT('妸') AND V_COMPARE <= F_NLSSORT('樲') THEN
T;?W(i(m+U2uu6R0 22 V_RETURN := V_RETURN || 'E';ITPUB个人空间!@:P0sG#PY/g^l
23 ELSIF V_COMPARE >= F_NLSSORT('发') AND V_COMPARE <= F_NLSSORT('猤') THENITPUB个人空间9fy
j4h9q4f WX
24 V_RETURN := V_RETURN || 'F';
Nw}OLj7js0 25 ELSIF V_COMPARE >= F_NLSSORT('旮') AND V_COMPARE <= F_NLSSORT('腂') THEN
.U9DK*O
B.[E/b0 26 V_RETURN := V_RETURN || 'G';ITPUB个人空间
|T~#MAO]
27 ELSIF V_COMPARE >= F_NLSSORT('妎') AND V_COMPARE <= F_NLSSORT('夻') THEN
tG/~K
F Kl N0 28 V_RETURN := V_RETURN || 'H';ITPUB个人空间7b%O
@&kf!g
29 ELSIF V_COMPARE >= F_NLSSORT('丌') AND V_COMPARE <= F_NLSSORT('攈') THENITPUB个人空间mkX1| g9K
}
30 V_RETURN := V_RETURN || 'J';
GSx$D7D2{l
vp0 31 ELSIF V_COMPARE >= F_NLSSORT('咔') AND V_COMPARE <= F_NLSSORT('穒') THEN
MFk-f/M0 32 V_RETURN := V_RETURN || 'K';
`;LGep$Ld S\'c0 33 ELSIF V_COMPARE >= F_NLSSORT('垃') AND V_COMPARE <= F_NLSSORT('擽') THENITPUB个人空间!T-^?ND4s2|9zs8l2h
34 V_RETURN := V_RETURN || 'L';
7Q"Sp4Q-R^/[0 35 ELSIF V_COMPARE >= F_NLSSORT('嘸') AND V_COMPARE <= F_NLSSORT('椧') THEN