在Oracle中获取汉字的拼音其实并不算复杂,这篇文章给出一个获取汉字拼音首字母的例子,并简单说明思路。
最近有个需求,要根据中文来获取汉语拼音的首字母。记得很早以前版主chensq和jlandzpa就给出过解决方法。不过这么简单的需求没有必要再去费劲找了,自己写一个就可以了。
介绍一下处理的思路,最简单的思路莫过于构造一个汉字库,手工为所有的汉字添加拼音,但是这种方法需要大量的人工录入工作,如果可以找到现成的字库倒是可以考虑。
那么能否利用Oracle提供的现有功能来解决。首先想到的是Oracle提供了SOUNDEX函数:
SQL> SELECT SOUNDEX('WORD') FROM DUAL;
SOUN
----
W630
SQL> SELECT SOUNDEX('词') FROM DUAL;
S
-
可惜的是,这个函数只对英文有效,对中文无效。看来只能使用其他的方法。
Oracle对各个国家不同的语言进行了本地化的开发,这其中就包括排序方式。查询了一下Oracle对于中文的排序支持,果然发现了对简体中文拼音的支持。
Oracle的SCHINESE_PINYIN_M排序方式可以支持中文的拼音排序,下面简单看一下使用这个中文拼音排序的例子:
SQL> WITH A AS
2 (SELECT '获取汉字拼音首字母' W FROM DUAL)
3 SELECT SUBSTR(W, ROWNUM, 1) FROM A
4 CONNECT BY ROWNUM <= (SELECT LENGTH(W) FROM A);
SU
--
获
取
汉
字
拼
音
首
字
母
已选择9行。
下面加上NLSSORT排序,并指定排序方法为SCHINESE_PINYIN_M:
SQL> WITH A AS
2 (SELECT '获取汉字拼音首字母' W FROM DUAL)
3 SELECT SUBSTR(W, ROWNUM, 1) FROM A
4 CONNECT BY ROWNUM <= (SELECT LENGTH(W) FROM A)
5 ORDER BY NLSSORT(SUBSTR(W, ROWNUM, 1), 'NLS_SORT=SCHINESE_PINYIN_M');
SU
--
汉
获
母
拼
取
首
音
字
字
已选择9行。
利用Oracle的现成的排序方法,编写获取拼音首字母的函数就十分容易了,只需要找到每个首字母对应开头汉字和结尾汉字,根据这些边界汉字进行比较,就可以找到当前汉字的首字母信息。
SQL> WITH A AS
2 (
3 SELECT ROWNUM RN, CHR(ROWNUM) C FROM DUAL CONNECT BY LEVEL <= 65535
4 )
5 SELECT * FROM A WHERE LENGTHB(C) = 2
6 AND RN > 32768
7 AND NLSSORT(C, 'NLS_SORT=SCHINESE_PINYIN_M') > NLSSORT('澳', 'NLS_SORT=SCHINESE_PINYIN_M')
8 AND NLSSORT(C, 'NLS_SORT=SCHINESE_PINYIN_M') < NLSSORT('巴', 'NLS_SORT=SCHINESE_PINYIN_M')
9 ORDER BY NLSSORT(C, 'NLS_SORT=SCHINESE_PINYIN_M');
RN C
---------- --
54931 謸
63179 鏊
62088 驁
45259 八
33172 仈
利用类似这样的方法,就可以分别找到每个首字母对应的字头和字尾。下面构建一个函数就十分容易了:
SQL> CREATE OR REPLACE FUNCTION F_PINYIN(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS
2 V_COMPARE VARCHAR2(100);
3 V_RETURN VARCHAR2(4000);
4
5 FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 AS
6 BEGIN
7 RETURN NLSSORT(P_WORD, 'NLS_SORT=SCHINESE_PINYIN_M');
8 END;
9 BEGIN
10
11 FOR I IN 1..NVL(LENGTH(P_NAME), 0) LOOP
12 V_COMPARE := F_NLSSORT(SUBSTR(P_NAME, I, 1));
13 IF V_COMPARE >= F_NLSSORT('吖') AND V_COMPARE <= F_NLSSORT('驁') THEN
14 V_RETURN := V_RETURN || 'A';
15 ELSIF V_COMPARE >= F_NLSSORT('八') AND V_COMPARE <= F_NLSSORT('簿') THEN
16 V_RETURN := V_RETURN || 'B';
17 ELSIF V_COMPARE >= F_NLSSORT('嚓') AND V_COMPARE <= F_NLSSORT('錯') THEN
18 V_RETURN := V_RETURN || 'C';
19 ELSIF V_COMPARE >= F_NLSSORT('咑') AND V_COMPARE <= F_NLSSORT('鵽') THEN
20 V_RETURN := V_RETURN || 'D';
21 ELSIF V_COMPARE >= F_NLSSORT('妸') AND V_COMPARE <= F_NLSSORT('樲') THEN
22 V_RETURN := V_RETURN || 'E';
23 ELSIF V_COMPARE >= F_NLSSORT('发') AND V_COMPARE <= F_NLSSORT('猤') THEN
24 V_RETURN := V_RETURN || 'F';
25 ELSIF V_COMPARE >= F_NLSSORT('旮') AND V_COMPARE <= F_NLSSORT('腂') THEN
26 V_RETURN := V_RETURN || 'G';
27 ELSIF V_COMPARE >= F_NLSSORT('妎') AND V_COMPARE <= F_NLSSORT('夻') THEN
28 V_RETURN := V_RETURN || 'H';
29 ELSIF V_COMPARE >= F_NLSSORT('丌') AND V_COMPARE <= F_NLSSORT('攈') THEN
30 V_RETURN := V_RETURN || 'J';
31 ELSIF V_COMPARE >= F_NLSSORT('咔') AND V_COMPARE <= F_NLSSORT('穒') THEN
32 V_RETURN := V_RETURN || 'K';
33 ELSIF V_COMPARE >= F_NLSSORT('垃') AND V_COMPARE <= F_NLSSORT('擽') THEN
34 V_RETURN := V_RETURN || 'L';
35 ELSIF V_COMPARE >= F_NLSSORT('嘸') AND V_COMPARE <= F_NLSSORT('椧') THEN
36 V_RETURN := V_RETURN || 'M';
37 ELSIF V_COMPARE >= F_NLSSORT('拏') AND V_COMPARE <= F_NLSSORT('瘧') THEN
38 V_RETURN := V_RETURN || 'N';
39 ELSIF V_COMPARE >= F_NLSSORT('筽') AND V_COMPARE <= F_NLSSORT('漚') THEN
40 V_RETURN := V_RETURN || 'O';
41 ELSIF V_COMPARE >= F_NLSSORT('妑') AND V_COMPARE <= F_NLSSORT('曝') THEN
42 V_RETURN := V_RETURN || 'P';
43 ELSIF V_COMPARE >= F_NLSSORT('七') AND V_COMPARE <= F_NLSSORT('裠') THEN
44 V_RETURN := V_RETURN || 'Q';
45 ELSIF V_COMPARE >= F_NLSSORT('亽') AND V_COMPARE <= F_NLSSORT('鶸') THEN
46 V_RETURN := V_RETURN || 'R';
47 ELSIF V_COMPARE >= F_NLSSORT('仨') AND V_COMPARE <= F_NLSSORT('蜶') THEN
48 V_RETURN := V_RETURN || 'S';
49 ELSIF V_COMPARE >= F_NLSSORT('侤') AND V_COMPARE <= F_NLSSORT('籜') THEN
50 V_RETURN := V_RETURN || 'T';
51 ELSIF V_COMPARE >= F_NLSSORT('屲') AND V_COMPARE <= F_NLSSORT('鶩') THEN
52 V_RETURN := V_RETURN || 'W';
53 ELSIF V_COMPARE >= F_NLSSORT('夕') AND V_COMPARE <= F_NLSSORT('鑂') THEN
54 V_RETURN := V_RETURN || 'X';
55 ELSIF V_COMPARE >= F_NLSSORT('丫') AND V_COMPARE <= F_NLSSORT('韻') THEN
56 V_RETURN := V_RETURN || 'Y';
57 ELSIF V_COMPARE >= F_NLSSORT('帀') AND V_COMPARE <= F_NLSSORT('咗') THEN
58 V_RETURN := V_RETURN || 'Z';
59 END IF;
60 END LOOP;
61 RETURN V_RETURN;
62 END;
63 /
函数已创建。
SQL> SELECT F_PINYIN('函数已创建。') FROM DUAL;
F_PINYIN('函数已创建。')
-------------------------------------------------------------------
HSYCJ
用类似的方法,获取一个汉字的整个拼音也是可行的,只不过确定字头字尾的工作会更加的繁琐。
需要说明的是,这种方法很难处理多音字,一般来说,多音字只能根据Oracle的排序中采用的拼音来返回结果。另外,Oracle实现的拼音排序难免存在错误,如果发现了错误,可以通过对个别字单独处理的方式来改写上面的代码。
这个函数在ZHS16GBK字符集下编写,不保证在其他字符集下也能正常工作,不过编写函数的思路应该是一样的。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-310271/ ,如需转载,请注明出处,否则将追究法律责任。