数字转英文
来自 PostgreSQL Wiki
跳转到导航跳转到搜索将数字值转换为英文
接收一个数字数据类型,将其转换为美式英语单词拼写。作者 Justin
313.90 into Three Hundred Thirteen and 90/100 cents
157,587.00 into One Hundred Fifty Seven Thousand Five Hundred Eighty Seven and Zero cents
它将转换到万亿(Quintillion)级别。
CREATE OR REPLACE FUNCTION spellNumericValue( pValue numeric)
RETURNS text AS
$BODY$
DECLARE
_dollar bigint = trunc(pValue)::text;
_cents int = ((pValue - trunc(pValue))*100)::int;
_spelledAmount text = '' ;
_brokenOut int[] ;
_pos integer = 0;
_word text ;
_tempVal int = 0 ;
BEGIN
--break the number down into separate elements each containing a max of 3
--digits. Number 23321456 is broken in array like so {456,321,23}
WHILE _dollar > 0 loop
_brokenOut = array_append(_brokenOut, (_dollar%1000)::int);
_dollar = trunc(_dollar/1000);
_pos = _pos + 1;
End Loop;
--this works on numbers between 1 to 999 transforming into english words, then goes to the
--next set of numbers in the array working backwards as the array was loaded backwards
--Meaning the highest value is the last element of the array _brokenOut
--This assumes words thousands millions, billions... occurs every 10^3
while _pos > 0 loop
_tempVal = _brokenOut[_pos] ; --use _tempVal to work on using the array directly has big performance hit.
if _tempVal >99 then
IF _tempVal > 899 THEN _spelledAmount = _spelledAmount || 'Nine Hundred ' ;
elsif _tempVal > 799 THEN _spelledAmount = _spelledAmount || 'Eight Hundred ' ;
elsif _tempVal > 699 THEN _spelledAmount = _spelledAmount || 'Seven Hundred ' ;
elsif _tempVal > 599 THEN _spelledAmount = _spelledAmount || 'Six Hundred ' ;
elsif _tempVal > 499 THEN _spelledAmount = _spelledAmount || 'Five Hundred ' ;
elsif _tempVal > 399 THEN _spelledAmount = _spelledAmount || 'Four Hundred ' ;
elsif _tempVal > 299 THEN _spelledAmount = _spelledAmount || 'Three Hundred ' ;
elsif _tempVal > 199 THEN _spelledAmount = _spelledAmount || 'Two Hundred ' ;
elsif _tempVal > 99 THEN _spelledAmount = _spelledAmount || 'One Hundred ' ;
end if ;
end if;
if _tempVal%100 = 10 THEN _spelledAmount = _spelledAmount || 'Ten ';
elsif _tempVal%100 = 11 THEN _spelledAmount = _spelledAmount || 'Eleven ';
elsif _tempVal%100 = 12 THEN _spelledAmount = _spelledAmount || 'Twelve ';
elsif _tempVal%100 = 13 THEN _spelledAmount = _spelledAmount || 'Thirteen ';
elsif _tempVal%100 = 14 THEN _spelledAmount = _spelledAmount || 'Fourteen ';
elsif _tempVal%100 = 15 THEN _spelledAmount = _spelledAmount || 'Fifteen ';
elsif _tempVal%100 = 16 THEN _spelledAmount = _spelledAmount || 'Sixteen ';
elsif _tempVal%100 = 17 THEN _spelledAmount = _spelledAmount || 'Seventeen ';
elsif _tempVal%100 = 18 THEN _spelledAmount = _spelledAmount || 'Eighteen ';
elsif _tempVal%100 = 19 THEN _spelledAmount = _spelledAmount || 'Nineteen ';
elsif _tempVal/10%10 =2 THEN _spelledAmount = _spelledAmount || 'Twenty ';
elsif _tempVal/10%10 =3 THEN _spelledAmount = _spelledAmount || 'Thirty ' ;
elsif _tempVal/10%10 =4 THEN _spelledAmount = _spelledAmount || 'Fourty ' ;
elsif _tempVal/10%10 =5 THEN _spelledAmount = _spelledAmount || 'Fifty ' ;
elsif _tempVal/10%10 =6 THEN _spelledAmount = _spelledAmount || 'Sixty ' ;
elsif _tempVal/10%10 =7 THEN _spelledAmount = _spelledAmount || 'Seventy ' ;
elsif _tempVal/10%10 =8 THEN _spelledAmount = _spelledAmount || 'Eighty ' ;
elsif _tempVal/10%10 =9 THEN _spelledAmount = _spelledAmount || 'Ninety ' ;
End if ;
if _tempVal%100 < 10 or _tempVal%100 > 20 then
if _tempVal%10 = 1 THEN _spelledAmount = _spelledAmount || 'One ';
elsif _tempVal%10 = 2 THEN _spelledAmount = _spelledAmount || 'Two ';
elsif _tempVal%10 = 3 THEN _spelledAmount = _spelledAmount || 'Three ';
elsif _tempVal%10 = 4 THEN _spelledAmount = _spelledAmount || 'Four ';
elsif _tempVal%10 = 5 THEN _spelledAmount = _spelledAmount || 'Five ';
elsif _tempVal%10 = 6 THEN _spelledAmount = _spelledAmount || 'Six ';
elsif _tempVal%10 = 7 THEN _spelledAmount = _spelledAmount || 'Seven ';
elsif _tempVal%10 = 8 THEN _spelledAmount = _spelledAmount || 'Eight ';
elsif _tempVal%10 = 9 THEN _spelledAmount = _spelledAmount || 'Nine ';
end if ;
end if ;
--Based on array element tells us which word to use.
--As the array is loaded backwards the highest value is
--highest array element number. To take it higher values all
--one needs to do is add more elsif statements.
If _pos = 2 then
_spelledAmount = _spelledAmount || 'Thousand ';
elsif _pos = 3 then
_spelledAmount = _spelledAmount || 'Million';
elsif _pos = 4 then
_spelledAmount = _spelledAmount || 'Billion ';
elsif _pos = 5 then
_spelledAmount = _spelledAmount || 'Trillion ';
elsif _pos = 6 then
_spelledAmount = _spelledAmount || 'Quadrillion ';
elsif _pos = 7 then
_spelledAmount = _spelledAmount || 'Quintillion ';
else
_spelledAmount = _spelledAmount || '';
end if;
_pos = _pos-1;
end loop;
--Functions primary purpose is to write out the amount on Checks
--this can be dropped out if you don't need it.
if pvalue <= 0.99 then
_spelledAmount = _spelledAmount || 'Zero Dollars ';
else
_spelledAmount = _spelledAmount || 'Dollars ';
end if ;
if _cents = 0 then
_spelledAmount = _spelledAmount || ' and Zero cents';
else
_spelledAmount = _spelledAmount || 'and ' || _cents::text || '/100 cents';
end if ;
return _SpelledAmount;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
结束语
此函数不转换小数部分。作者尚未找到任何关于如何将小数部分写成英文的结论性或普遍接受的方法。这就是小数部分被保留为两位小数精度,并除以 100 的原因。