oracle里数字分金额转成大写汉字金额程序(转贴)

CREATE OR REPLACE FUNCTION CONVERT_MONEY(INPUT_NBR IN NUMBER DEFAULT 0)
/*
函数名称: CONVERT_MONEY
用 于: 将以分为单位输入的数值转换为大写汉字形式
注 释: 当转换后的汉字以分结尾时,不加“整”,当以角或元结尾时加“整”,这符合银行的规定。
数字金额凡是中间出现0的,必须转为大写的“零”,连续多个0时只转为一个“零”字,
结尾出现0时要加“整”,结尾不是0时不加“整”,这与前面的规定是一致的。
由于圆是货币单位,所以在多于1元钱时,圆是必须出现的。但是,万佰等是数字单位,有
时可能不出现。

代码:--------------------------------------------------------------------------------
*/
RETURN VARCHAR2 IS
INPUT_NBR_BAK NUMBER(20); /*用于接收输入参数 INPUT_NBR */
NUM_CHARACTER VARCHAR2(20) := '零壹贰叁肆伍陆柒捌玖';
UNIT_CHARACTER VARCHAR2(40) := '分角圆拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿';
OUTPUT_STRING VARCHAR2(100):= '';
REMAIN_NBR NUMBER(20);
BIT_NUM NUMBER(20); /*每一位上的数字*/
BIT_UNIT VARCHAR2(2); /*每一位所对的单位*/
BIT_INDIC NUMBER(1) :=0; /*每一位的数字是否为0,0表示为0,1表示不为0*/
I NUMBER(2) :=0; /*循环次数,索引变量从0开始*/
SPE_UNIT VARCHAR2(2):='A';/*特殊位,包括万和亿,表示该亿汉字是否已写入结果字串*/
SIGN_INDIC VARCHAR2(1); /*用于标志数值符号:0为正,1为负*/
BEGIN
IF INPUT_NBR=0 THEN RETURN '零圆整';
ELSIF INPUT_NBR>0 THEN SIGN_INDIC:='0';
INPUT_NBR_BAK:=INPUT_NBR;
ELSIF INPUT_NBR<0 THEN SIGN_INDIC:='1';
INPUT_NBR_BAK:=-INPUT_NBR;
END IF;
LOOP
REMAIN_NBR := FLOOR(INPUT_NBR_BAK / 10); /*取出除后的商*/
BIT_NUM := INPUT_NBR_BAK - REMAIN_NBR * 10; /*取出当前位的数值*/
INPUT_NBR_BAK := REMAIN_NBR; /*保存商以做下一次循环*/
BIT_UNIT := RTRIM(SUBSTR(UNIT_CHARACTER, I * 2+ 1, 2));/*取出当前位的单位汉字*/

IF BIT_NUM > 0 THEN /*当前位的值不为0*/
BIT_INDIC :=1;
IF I=6 OR I=14 THEN /*当前位是'万'位或'万亿'位*/
SPE_UNIT:='万'; /*表示万已经写入OUTPUT_STRING中,在BIT_UNIT中会包含万字*/
ELSIF (I>=7 AND I<=9) OR (I>=15 AND I<=17) THEN /*当前位在万及千万之间或万亿及千万亿之间*/
IF SPE_UNIT!='万' THEN /*万还没写入OUTPUT_STRING中,则要写入一次*/
OUTPUT_STRING:='万'||OUTPUT_STRING;
SPE_UNIT:='万'; /*表示万已经写入OUTPUT_STRING中*/
END IF;
END IF; /*高于千万亿的数本程序不考虑了*/
OUTPUT_STRING := SUBSTR(NUM_CHARACTER, BIT_NUM * 2 + 1, 2)||BIT_UNIT||OUTPUT_STRING;
ELSE /*当前位等于0时,走此分支*/
IF BIT_INDIC = 1 THEN /*当前位的前一位不为0时写 零 */
OUTPUT_STRING := '零'||OUTPUT_STRING;
END IF;
IF BIT_UNIT IN ('圆','亿') THEN /*若已达圆位,则圆是必须出现的,由于亿太大,不与万相同处理,所以就与圆一样处理*/
SPE_UNIT:=BIT_UNIT; /*保存圆与亿,以与万相区别*/
OUTPUT_STRING := BIT_UNIT||OUTPUT_STRING;
END IF;
BIT_INDIC :=0; /*当前位的值为0*/
END IF;
I := I + 1;
EXIT WHEN INPUT_NBR_BAK = 0;
END LOOP;

IF MOD(INPUT_NBR,10)=0 THEN /*输入的数字没有分,最小的是角,则尾部串个整*/
OUTPUT_STRING:=OUTPUT_STRING||'整';
END IF;
IF SIGN_INDIC='1' THEN
OUTPUT_STRING:='负'||OUTPUT_STRING;
END IF;
RETURN OUTPUT_STRING;
END;
/

[更正]对于我的“数字分金额转成大写汉字元金额程序!”一文的更正
本网站的广大网友、ORACLE爱好者及使用者们:

我是流云飞天,曾于2002年1月10号在此论坛发表过一篇题为《数字分金额转成大写汉字元金额程序!》的文章。拙文有幸被coolsword版主置入精华区(http://www.itpub.net/showthread.php?s=&threadid=12210),此举对我鼓舞甚大。

今日收到网友weijsh的来信,内容如下:

我在itpub中看到你的贴子,运行如下,为什么会出错?谢谢
SQL> select CONVERT_MONEY(12.3) from dual;
select CONVERT_MONEY(12.3) from dual
*
ERROR 位于第 1 行:
ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小
ORA-06512: 在"SYS.CONVERT_MONEY", line 25
ORA-06512: 在line 1


SQL> select CONVERT_MONEY from dual;

CONVERT_MONEY
-------------------------------------------------------

零圆整

SQL> select CONVERT_MONEY(12) from dual;
select CONVERT_MONEY(12) from dual
*
ERROR 位于第 1 行:
ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小
ORA-06512: 在"SYS.CONVERT_MONEY", line 25
ORA-06512: 在line 1

我在我现在用的数据库上做了试验,也出现了同样的错误。后来,我把以下两句:

BIT_UNIT := RTRIM(SUBSTR(UNIT_CHARACTER, I * 2+ 1, 2));/*取出当前位的单位汉字*/
OUTPUT_STRING := SUBSTR(NUM_CHARACTER, BIT_NUM * 2 + 1, 2)||BIT_UNIT||OUTPUT_STRING;

中的数字 2 改为 1 后,即:

BIT_UNIT := RTRIM(SUBSTR(UNIT_CHARACTER, I * 1+ 1, 1));/*取出当前位的单位汉字*/
OUTPUT_STRING := SUBSTR(NUM_CHARACTER, BIT_NUM * 1 + 1, 1)||BIT_UNIT||OUTPUT_STRING;

程序运行正常。

我对此的理解是:这个函数是我在原来的数据库上编写的,那个数据库是英文的字符集;而我现在用的数据库是中文的字符集。SUBSTR函数的功能是,从第X个字符开始,取Y个字符。这样,在两种不同字符集下给出的结果是不同的。

对于网友weijsh提出的问题表示感谢,同是也向大家表示歉意。

最后补充一句,如果想从数据库里看语言及字符集的话,请以DBA权限的用户登录,执行以下语句:
select * from v$nls_parameters;
以下是在我现在用的数据库上执行的结果:
NLS_LANGUAGE
SIMPLIFIED CHINESE

NLS_TERRITORY
CHINA

NLS_CURRENCY
RMB

NLS_ISO_CURRENCY
CHINA

NLS_NUMERIC_CHARACTERS

.,

NLS_CALENDAR
GREGORIAN

NLS_DATE_FORMAT
DD-MON-RR

NLS_DATE_LANGUAGE
SIMPLIFIED CHINESE

NLS_CHARACTERSET
ZHS16GBK


NLS_SORT
BINARY

NLS_TIME_FORMAT
HH.MI.SSXFF AM

NLS_TIMESTAMP_FORMAT
DD-MON-RR HH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT
HH.MI.SSXFF AM TZH:TZM


NLS_TIMESTAMP_TZ_FORMAT
DD-MON-RR HH.MI.SSXFF AM TZH:TZM

NLS_DUAL_CURRENCY
RMB

NLS_NCHAR_CHARACTERSET
ZHS16GBK

NLS_COMP
BINARY

另外,我的“数字分金额转成大写汉字元金额”函数,如果输入小数的话,在赋值时ORACLE会自动作四舍五入处理。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/68303/viewspace-251555/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/68303/viewspace-251555/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值