使用COMPOSE和UNISTR编写重音符号

开发者在线 Builder.com.cn 更新时间:2004-10-14作者:Builder.com 来源:

本文关键词: ScottStephens oracletips

本文译自Builder.com,未经许可请勿转载

在没有查询Unicode值方法,或者没有使用Unicode编辑器的情况下很难使用ASCII字符编写代码。

Oracle9i引入了一个COMPOSE函数,这一函数允许你使用一系列的Unicode字符,并规则化文本。这就意味着,它可以输入一个字母,比如'a' (Unicode字符为0097),以及字符的标记,比如重音符(Unicode字符0300),并建立这两个标记的联合的单一字符。COMPOSE使用特定的联合标记,即Unicode标准,而不是ASCII标点符号。由此其结果为Unicode字符OOEO(具有重音符的小写拉丁字母’a’):

INSI中的绝大部分普通联合字符为:

U+0300: grave accent ( ` )

U+0301: acute accent ( ' )

U+0302: circumflex accent(^)

U+0303: tilde (~)

U+0308: umlaut

 

在没有其它特定软件或者键盘驱动程序的情况下,很难利用键盘输入Unicode字符0097和0300。所以,在一个纯ASCII文本中输入Unicode字符顺序的一种方法是采用UNISTR函数。这一函数使用一个ASCII字符串,并建立一系列的Unicode字符。它使用十六进制的顺序与任何非ASCII字符相互映射,这与JAVA的方法相类似。

为了输入a字母以及其之后的重音联合字符的次序,你可以使用UNISTR('a300'),而不是在代码直接输入这些字符。这一函数可以正确地运行在基于Unicode的任何字符集和数据库。你可以在函数中写入更多的联合字符,可以在UNISTR函数中包含ASCII与Unicode字符的混合。例如,可以这样编写:

select COMPOSE(UNISTR('Unless you are nai308ve, meet me at the cafe301 with

your re301sume301.')) from dual;

 

当你使用COMPOSE函数结合函数的输出时,在无需查询每一单一值的情况下,你可以生成一个Unicode字符。例如:

select 'it is true' if compose(unistr('a300')) = unistr('0e0');

 

COMPOSE函数返回一个NVARCHAR2字符串,这一字符串通常为Unicode形式。当在本地使用这些字符时,数据库将会企图将这些字符映射到本地字符集,并非所有字符都会被映射,有一些字符不会在COMPOSE函数中操作,因为Unicode社团还没有在Oracle数据库中定义它们。

为了能快速检查特定环境中的字符,你可以运行一个类似于以下代码段的程序,以查看联合字符如何与输出相映射。你需要查找NLS_LANG环境以确保这些字符正确返回:

create or replace type hexrange_tbl as table of varchar2(4);

/

show errors;

 

create or replace function hexrange(n1 varchar2,n2 varchar2)

    returnhexrange_tbl pipelined

is

begin

    fori in to_number(n1,'000X') .. to_number(n2,'000X') loop

        pipe row(to_char(i,'FM000X'));

    end loop;

    return;

endhexrange;

/

show errors;

 

selectcolumn_value composer,

    compose(unistr('a'||column_value)) a,

    compose(unistr('c'||column_value)) c,

    compose(unistr('e'||column_value)) e,

    compose(unistr('i'||column_value)) i,

    compose(unistr('n'||column_value)) n,

    compose(unistr('o'||column_value)) o,

    compose(unistr('r'||column_value)) r,

    compose(unistr('s'||column_value)) s,

    compose(unistr('u'||column_value)) u,

    compose(unistr('y'||column_value)) y

 from table(hexrange('0300','0327')) x;

 

这里开个玩笑。这儿一个使用COMPOSE和UNISTR的简短PL/SQL程序,世界上很多SMS用户,黑客,以及Spammers都会利用这一程序使得很多难读的英文文本变得可读性。我使用DBMS_RANDOM任意地选择被用于不同字符的联合字符,然后让SQL生成ANSI/Latin-1输出。

setserveroutput on;

declare

    a_combnvarchar2(50) := unistr('30030130230330830A');

    c_combnvarchar2(50) := unistr('327');

    e_combnvarchar2(50) := unistr('300301302308');

    i_combnvarchar2(50) := unistr('300301308');

    n_combnvarchar2(50) := unistr('303');

    o_combnvarchar2(50) := unistr('300301302303308');

    u_combnvarchar2(50) := unistr('300301302308');

    y_combnvarchar2(50) := unistr('301308');

    l_idx integer;

    l_enamenvarchar2(50);

    chnchar;

    l_junkvarchar2(50);

begin

    dbms_random.initialize(to_char(sysdate,'SSSSS'));

    for row in (select ename from emp) loop

        l_ename := row.ename;

        l_junk := null;

        fori in 1..length(l_ename) loop

            ch := substr(l_ename,i,1);

            case lower(ch)

            when 'a' then

                l_junk := l_junk || compose(ch || substr(a_comb,

                    mod(abs(dbms_random.random),length(a_comb)) + 1,1));

            when 'c' then

                l_junk := l_junk || compose(ch || substr(c_comb,

                    mod(abs(dbms_random.random),length(c_comb)) + 1,1));

            when 'e' then

                l_junk := l_junk || compose(ch || substr(e_comb,

                    mod(abs(dbms_random.random),length(e_comb)) + 1,1));

            when 'i' then

                l_junk := l_junk || compose(ch || substr(i_comb,

                    mod(abs(dbms_random.random),length(i_comb)) + 1,1));

            when 'n' then

                l_junk := l_junk || compose(ch || substr(n_comb,

                    mod(abs(dbms_random.random),length(n_comb)) + 1,1));

            when 'o' then

                l_junk := l_junk || compose(ch || substr(o_comb,

                    mod(abs(dbms_random.random),length(o_comb)) + 1,1));

            when 'u' then

                l_junk := l_junk || compose(ch || substr(u_comb,

                    mod(abs(dbms_random.random),length(u_comb)) + 1,1));

            when 'y' then

                l_junk := l_junk || compose(ch || substr(y_comb,

                    mod(abs(dbms_random.random),length(y_comb)) + 1,1));

            else

                l_junk := l_junk || ch;

            end case;

        end loop;

        dbms_output.put_line(to_char(l_junk));

    end loop;

end;

/

show errors;

 

 


Scott Stephens:已经在Oracle公司工作大于13年之久,他的工作领域包括技术支持,电子商务,市场开发,以及软件开发。


责任编辑:李宁

欢迎评论投稿

用户评论

  • 用户名
  • 评论内容