How SQL Server creates language helper functions

Source: Internet
Author: User
Tags case statement

In a globalized environment like this, because there are many different grammatical rules in different languages, many of the simple tasks of the past now become difficult. You can generalize a particular language by dividing it into a set of grammatical rules and exceptions to these rules (and a basic word). In some programming languages, such as Perl and Java, there are common domain modules that can be used to complete language transformations on text.

Here's a slightly simpler example, assuming we want to convert a number to its spelling version (for example, a check and a legal contract are required). This trick has been in the early days of Oracle, and is generally used in the following ways:

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

The To_date function converts a number to a date using the Julian date format. To_char then accepts a date parameter and formats it again as a string that represents the version of the spelling number for the Julian date. But there are some limitations to the know-how.

First, the maximum valid value for the Julian date in Oracle is 9999, so the maximum date value can only be 5373484, and the minimum value is 1 or 4712BC. Also, because there is no "0" year, it is not possible to generate the text "0" without using an additional DECODE or case statement. The third big limitation is that it ignores your NLS settings. No matter what language you use, the numbers are always spelled out in American English. Some simple operations also have such problems, such as spelling out the day. For example, try to generate the Spanish phrase "Cinco de Mayo":

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

The syntax involved in generating numbers for most languages is actually fairly straightforward. Body work involves collecting all the different grammatical rules and establishing enough rules to generate the correct syntax patterns. (Now I'm going to avoid issues that involve matching numbers and gender.) )

First, I'll create two tables: The first table holds basic words and exceptions, and the second table holds some simple template patterns for generating text. If there is a number in the first table, then my language function returns that text. For each of the other numbers, I will try to match it in a series of patterns and apply a template to generate the correct text.

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)
  );

The following is the code needed to generate a numeric spelling version. Here I will follow the cardinality (such as 1, 2, and 3), and in fact, these functions can generate ordinals (1th, 2nd, third) and plural versions by listing more exceptions and patterns for each language.

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 < then


Return replace (row.temp0, ' ~2 ', Cardinal (v));


End If;


Else


If v = 0 Then


return replace (row.temp0, ' ~ ', cardinal (n/p));


Else


return replace (replace NVL (row.temp, ' ~ ~2 '),


' ~ ', cardinal (n-v),


' ~2 ', Cardinal (v));


End If;


End If;


End If;


end Loop;


return ' number TOO LARGE ';


end Cardinal;


End Genword;


  /


Show errors;

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.