Sql server如何建立語言輔助函數

來源:互聯網
上載者:User

在現在這樣一個全球化環境中,因為在不同的語言中有很多不同的文法規則,所以以前很多簡單的任務現在都變得很困難。你可以將一門特定的語言分成一組文法規則和針對這些規則的異常(以及一個基本詞語),從而將這些任務一般化。在一些程式設計語言(比如 Perl 和 Java)中,有一些公用域(domain)模組可以用來對文本完成語言轉換。

下面給出一個稍微簡單一點兒的例子,假設我們要將一個數字轉換成其拼字版本(例如需要填寫支票和法律合約)。這個訣竅在 Oracle 出現的早期已經有了,一般都以如下方式使用:

selectto_char(to_date(12345,'J'),'Jsp') from dual;
  
  Twelve Thousand Three Hundred Forty-Five

TO_DATE 函數使用 Julian 日期格式將數字轉換成一個日期。然後,TO_CHAR 接受一個日期參數並再次將其格式化為一個表示 Julian 日期的拼字數字版本的字串。但是這個決竅有一些限制。

首先,在 Oracle 中 Julian 日期的最大有效值是9999年,所以日期的最大值只能取到5373484,而最小值是1或4712BC。而且,因為沒有第“零”年,所以如果不額外使用一個 DECODE 或 CASE 語句就不可能產生文本“零”。第三個大的限制是它會忽略掉你的 NLS 設定。不管你使用的是哪種語言,數字總是以美國英語拼字出。一些簡單的操作也存在這樣的問題,比如拼字出天。例如,嘗試產生西班牙語短語“Cinco de Mayo”:

 alter session set nls_language = 'SPANISH';
  select to_char(to_date('0505','MMDD'),'Ddspth Month') from dual;
  
  Fifth Mayo

在為大多數語言產生數字時涉及的文法實際上相當簡單。主體工作包括收集所有不同的文法規則並建立起足夠的規則來產生正確的文法模式。(現在我將迴避涉及到匹配數字和性別的問題。)

首先,我將建立兩個表:第一個表儲存基本的單詞和異常,第二個表儲存用於產生文本的一些簡單的模板模式。如果在第一個表中有數字,那麼我的語言函數就返回那個文本。對於其它每個數字,我將試圖在一系列模式中匹配它,並應用一個模板來產生正確的文本。

create table numwords
  (
    lang  varchar2(2),
    num   integer,
    word  varchar2(30),
    constraint numwords_pk primary key (lang,num)
  );
  
  create table numrules
  (
    lang  varchar2(2),
    seq   integer,
    p1   integer,
    p2   integer,
    temp0  varchar2(30),
    temp  varchar2(30),
    constraint numrules_pk primary key (lang,seq)
  );

下面是產生一個數字拼字版本所需的代碼。這裡我將按照基數來(比如1、2和3);而事實上,這些函數可以通過為每種語言列出更多異常和模式來產生序數(第1、第2、第三)和複數版本。

REM -- create a table of base words and exceptions
  create or replace package genword
  as
    function get_word(n number) return varchar2;
    function cardinal(n number) return varchar2;
  end genword;
  /
  show errors;
  
  create or replace package body genword
  as
    function get_word(n number) return varchar2
    is
      l_wordnumwords.word%type;
    begin
      select word into l_word from numwords
       where lang = sys_context('userenv','lang') and num = n;
      return l_word;
    exception
      when no_data_found then
        return null;
    end;
    --
    function cardinal(n number) return varchar2
    is
      p number;    -- power
      t varchar2(30); -- template
      v number;    -- lower portion
      l_word   numwords.word%type;
    begin
      if n < 0 then
        l_word := get_word(-1);
        if l_word is null then
          return null;
        end if;
        return l_word||' '||cardinal(-n);
      end if;
      l_word := get_word(n);
      if l_word is not null then
        return l_word;
      end if;
      for row in
      (
        select * from numrules
         where lang = sys_context('userenv','lang')
         order by seq
      )
      loop
        if length(n) <= row.p1 + row.p2 then
          p := power(10,row.p2);
          v := mod(n,p);
          if row.seq = 0 then
            if n < 20 then
              return replace(row.temp0,'~2',cardinal(v));
            end if;
          else
            if v = 0 then
              return replace(row.temp0,'~1',cardinal(n/p));
            else
              return replace(replace(nvl(row.temp,'~1 ~2'),
                '~1',cardinal(n-v)),
                '~2',cardinal(v));
            end if;
          end if;
        end if;
      end loop;
      return 'NUMBER TOO LARGE';
    end cardinal;
  end genword;
  /
  show errors;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.