Oracle:将数字转换为除英语之外的其他语言的单词

时间:2016-12-15 14:59:48

标签: oracle plsql

我试图用文字转换数字。

select to_char(to_date(:number,'j'),'jsp') from dual;



SELECT TO_CHAR (TO_DATE (24834, 'j'), 'jsp') FROM DUAL;
//Output: twenty-four thousand eight hundred thirty-four

但问题是我需要转换其他语言的数字而不是英语。也许你有任何想法如何做到这一点?

我需要转换成拉脱维亚语。

3 个答案:

答案 0 :(得分:2)

这是一个很酷的技巧(采用Julian和SPell的jsp格式)。我找到了Ask Tom article,它提供了更多细节。但基本上jsp格式只适用于英语,但你可以将它包装在一个函数中并将英语翻译成另一种语言。

例如,Tom的spell_number函数如下:

create or replace 
 function spell_number( p_number in number ) 
 return varchar2 
 as 
 type myArray is table of varchar2(255); 
 l_str myArray := myArray( '', 
 ' thousand ', ' million ', 
 ' billion ', ' trillion ', 
 ' quadrillion ', ' quintillion ', 
 ' sextillion ', ' septillion ', 
 ' octillion ', ' nonillion ', 
 ' decillion ', ' undecillion ', 
 ' duodecillion ' ); 

 l_num varchar2(50) default trunc( p_number ); 
 l_return varchar2(4000); 
 begin 
 for i in 1 .. l_str.count 
 loop 
 exit when l_num is null; 

 if ( substr(l_num, length(l_num)-2, 3) <> 0 ) 
 then 
 l_return := to_char( 
 to_date( 
 substr(l_num, length(l_num)-2, 3), 
 'J' ), 
 'Jsp' ) || l_str(i) || l_return; 
 end if; 
 l_num := substr( l_num, 1, length(l_num)-3 ); 
 end loop; 

 return l_return; 
 end; 
 /

法语(显然)的版本只使用spell_number和一些法语翻译:

create or replace 
function spell_number_french( p_number in number ) 
return varchar2 
as 
begin 
return replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( replace( replace( replace( replace( 
replace( 
lower( spell_number( p_number )) 
, 'duodecillion', 'bidecillion' ) 
, 'quintillion' , 'cintillion' ) 
, 'billion' , 'milliard' ) 
, 'thousand' , 'mille' ) 
, 'hundred' , 'cent' ) 
, 'ninety' , 'quatre-vingt-dix') 
, 'eighty' , 'quatre-vingt' ) 
, 'seventy' , 'soixante-dix' ) 
, 'sixty' , 'soixante' ) 
, 'fifty' , 'cinquante' ) 
, 'forty' , 'quarante' ) 
, 'thirty' , 'trente' ) 
, 'twenty' , 'vingt' ) 
, 'nineteen' , 'dix-neuf' ) 
, 'eighteen' , 'dix-huit' ) 
, 'seventeen' , 'dix-sept' ) 
, 'sixteen' , 'seize' ) 
, 'fifteen' , 'quinze' ) 
, 'fourteen' , 'quatorze' ) 
, 'thirteen' , 'treize' ) 
, 'twelve' , 'douze' ) 
, 'eleven' , 'onze' ) 
, 'ten' , 'dix' ) 
, 'nine' , 'neuf' ) 
, 'eight' , 'huit' ) 
, 'seven' , 'sept' ) 
, 'five' , 'cinq' ) 
, 'four' , 'quatre' ) 
, 'three' , 'trois' ) 
, 'two' , 'deux' ) 
, 'one' , 'un' ) 
, 'dix-six' , 'seize' ) 
, 'dix-cinq' , 'quinze' ) 
, 'dix-quatre' , 'quatorze' ) 
, 'dix-trois' , 'treize' ) 
, 'dix-deux' , 'douze' ) 
, 'dix-un' , 'onze' ) 
, '-un ' , '-une ' ) 
, 'un cent' , 'cent' ) 
, 'un mille' , 'mille' ) 
, 'une' , 'un' ); 
end spell_number_french; 

做一些类似于您选择的语言的事情。请参阅Ask Tom链接以获得更详细的讨论。

答案 1 :(得分:0)

像这样?

SELECT TO_CHAR (SYSDATE, 'DD/MON/YYYY',
'nls_date_language=''Traditional Chinese'' ') FROM DUAL

我不确定拉脱维亚语,您需要查看有关支持语言的手册

答案 2 :(得分:0)

我能看到的唯一方法是构建一个翻译表并将此翻译应用于字符串。 例如,假设您有以下翻译:

create table translate (eng, lat) as
(
select 'twenty',   'TWENTY' from dual union all
select 'thousand', 'THOUSAND' from dual union all
select 'eight',    'EIGHT' from dual union all
select 'four',     'FOUR' from dual union all
select 'hundred',  'HUNDRED' from dual union all
select 'thirty',   'THIRTY' from dual
) 

你可以尝试:

with test(s) as (SELECT replace(TO_CHAR (TO_DATE (24834, 'j'), 'jsp'), '-', ' - ') FROM DUAL)
select replace ( listagg ( nvl(lat, tk), ' ') within group ( order by position), ' - ', '-')
from (
        SELECT regexp_substr(s, '[^ ]+', 1, level) as tk, level as position
          FROM test
        CONNECT BY instr(s, ' ', 1, level - 1) > 0
     ) tokens
left outer join translate tr
  on (tr.eng = tokens.tk)
order by position

给出:

TWENTY-FOUR THOUSAND EIGHT HUNDRED THIRTY-FOUR

内部查询是一个字符串拆分器,用于构建英文字符串中的标记列表;该字符串被视为由空格分隔的标记列表。

外部部分只是加入这个令牌列表来获取翻译,注意使用NVL来处理我认为是令牌的'-'

replace首先用空格包装'-'个字符,这样它们就会被认为是分开的标记购买拆分器,然后删除添加的空格,恢复初始结构字符串。

这样您就不需要对翻译进行硬编码,但您可以将其作为数据处理。

请注意,这假设英语和拉脱维亚语在数字拼写方面的唯一区别在于单个单词,而不在结构中(我无法检查假设是否为真)。

相关问题