从 cmets 看来,您从一个想要转换为单词的数值开始,您应该首先将其拆分为美元和美分。
如果你真的需要使用substr等,那么你可以从一个已知的格式开始,比如to_char(amount,'fm9990.00'),所以它会是一个正好有两位小数的字符串。但是,如果您有数值,则使用算术函数将其转换为所需的单位会更容易。整美元是trunc(amount),美分是100 * mod(amount,1)。
另一个问题是'Jsp' 日期格式方法无法处理零。如果您使用的是 Oracle 12.2 或更高版本,则可以使用 default on conversion error 子句的解决方法:
create table demo
( amount number(6,2) );
insert into demo values (10.3);
insert into demo values (.25);
insert into demo values (25);
select amount
, nvl(to_char(to_date(trunc(amount) default null on conversion error,'J'),'Jsp'),'Zero') as dollars
, nvl(to_char(to_date(100 * mod(amount,1) default null on conversion error,'J'),'Jsp'),'Zero') as cents
from demo;
AMOUNT DOLLARS CENTS
-------- ------------ -------------
10.30 Ten Thirty
25.00 Twenty-Five Zero
0.25 Zero Twenty-Five
在 12.1 中,您可以使用内联函数绕过它(即使在以后的版本中也可能不是一个坏主意,以简化查询的其余部分):
with
function to_words(num number) return varchar2 as
begin
return
case num
when 0 then 'Zero'
else to_char(to_date(num,'J'),'Jsp')
end;
end;
select amount
, to_words(trunc(amount)) as dollars
, to_words(100 * mod(amount,1)) as cents
from demo;
对于大于 5373484 的值(日期 '9999-12-31' 的儒略表示),您可以从 Ask Tom: Spell the number 使用它(此处转换为 WITH 子句,但您可以将其创建为独立函数):
with function spell_number
( p_number in number )
return varchar2
as
-- Tom Kyte, 2001:
-- https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1407603857650
l_num varchar2(50) := trunc(p_number);
l_return varchar2(4000);
type myarray is table of varchar2(15);
l_str myarray :=
myarray
( ''
, ' thousand '
, ' million '
, ' billion '
, ' trillion '
, ' quadrillion '
, ' quintillion '
, ' sextillion '
, ' septillion '
, ' octillion '
, ' nonillion '
, ' decillion '
, ' undecillion '
, ' duodecillion ');
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;
select amount
, spell_number(trunc(amount)) as dollars
, spell_number(100 * mod(amount,1)) as cents
from demo
/