今天工作中遇到了要改货币金额转换为大写显示的需求,找到了一些前辈们的代码,总结了一下贴出来,以备以后查看学习使用.
1.专门用于转化年份的函数TO_UPPER_YEAR.
-
CREATE OR REPLACE FUNCTION TO_UPPER_YEAR(YEAR_IN IN VARCHAR2)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
STR VARCHAR2(32767) := '〇一二三四五六七八九';
-
-
-
-
-
FOR I IN 1 .. LENGTH(YEAR_IN)
-
-
SELECT SUBSTR(STR, SUBSTR(YEAR_IN,I, 1) + 1, 1)
-
-
-
RESULT := RESULT || TEMP;
-
-
-
-
-
DBMS_OUTPUT.PUT_LINE(SQLERRM);
-
-
2.用于阿拉伯数字转化为大写汉字的函数TO_UPPER_NUM.
-
CREATE OR REPLACE FUNCTION TO_UPPER_NUM
-
-
P_NUM IN NUMBER DEFAULT NULL,
-
P_ROUND NUMBER DEFAULT 2, --输出要保留的小数位数
-
P_MONTH NUMBER DEFAULT 1 --输出不为月份或者日时,当此参数输入不为1时,返回值为大写(非汉字)数字
-
-
-
-
-
-
*输入参数转换前的数字,要保留的小数位数(4舍5入可以不输入,默认为小数点后2位)
-
-
-
*支持转换月份和日期,如 SELECT TO_UPPER_NUM('31','3','2') FROM DUAL
-
-
* SELECT TO_UPPER_YEAR(TO_CHAR(SYSDATE,'YYYY')) || '年' ||
-
* TO_UPPER_NUM(TO_CHAR(SYSDATE,'MM'),'2','2') || '月' ||
-
* TO_UPPER_NUM(TO_CHAR(SYSDATE,'DD'),'2','2') || '日'
-
-
-
* SELECT TO_UPPER_NUM(1234.564) FROM dual ;
-
-
RESULT NVARCHAR2(100) := ''; --返回大写汉字字符串
-
NUM_ROUND NVARCHAR2(100) := TO_CHAR(ABS(ROUND(P_NUM, P_ROUND))); --转换数字为小数点后p_round位的字符(正数)
-
NUM_LEFT NVARCHAR2(100); --小数点左边的数字
-
NUM_RIGHT NVARCHAR2(100); --小数点右边的数字
-
STR1 NCHAR(10) := '零壹贰叁肆伍陆柒捌玖'; --数字大写
-
STR2 NCHAR(16) := '点拾佰仟万拾佰仟亿拾佰仟万拾佰仟'; --数字位数(从低至高)
-
STR3 NCHAR(10) := '〇一二三四五六七八九'; --月份数字大写
-
STR4 NCHAR(16) := '点十佰仟万拾佰仟亿拾佰仟万拾佰仟'; --数字位数(从低至高)
-
NUM_PRE NUMBER(1) := 1; --前一位上的数字
-
NUM_CURRENT NUMBER(1); --当前位上的数字
-
NUM_COUNT NUMBER := 0; --当前数字位数
-
-
-
-
-
-
-
-
-
-
-
-
SELECT TO_CHAR(NVL(SUBSTR(TO_CHAR(NUM_ROUND),
-
-
DECODE(INSTR(TO_CHAR(NUM_ROUND), '.'),
-
-
-
INSTR(TO_CHAR(NUM_ROUND), '.') - 1)),
-
-
-
-
-
SELECT SUBSTR(TO_CHAR(NUM_ROUND),
-
DECODE(INSTR(TO_CHAR(NUM_ROUND), '.'),
-
-
-
INSTR(TO_CHAR(NUM_ROUND), '.') + 1),
-
-
-
-
--数字整数部分超过16位时.采用从低至高的算法,先处理小数点左边的数字
-
IF LENGTH(NUM_LEFT) > 16 THEN
-
-
-
FOR I IN REVERSE 1 .. LENGTH(NUM_LEFT) LOOP
-
-
NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_LEFT, I, 1)); --当前位上的数字
-
NUM_COUNT := NUM_COUNT + 1; --当前数字位数
-
-
-
--如果转换数字最高位是十位,转换后不需要前面的壹,如月份12转换后为拾贰,则
-
IF NUM_CURRENT = 1 AND P_MONTH <> 1 AND NUM_COUNT = 2 THEN
-
RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;
-
-
-
RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1)
-
||SUBSTR(STR2, NUM_COUNT, 1)
-
-
-
-
-
IF MOD(NUM_COUNT - 1, 4) = 0 THEN
-
-
RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;
-
NUM_PRE := 0; --点、万,亿前不准加零
-
-
IF NUM_PRE > 0 OR LENGTH(NUM_LEFT) = 1 THEN
-
-
RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1) || RESULT;
-
-
-
-
-
-
IF LENGTH(NUM_RIGHT) > 0 THEN
-
FOR I IN 1 .. LENGTH(NUM_RIGHT) LOOP
-
-
NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_RIGHT, I, 1)); --当前位上的数字
-
RESULT := RESULT || SUBSTR(STR1, NUM_CURRENT + 1, 1);
-
-
-
RESULT := REPLACE(RESULT, '点', ''); --无小数时去掉点
-
-
-
-
-
-
-
-
-
DBMS_OUTPUT.PUT_LINE(SQLERRM);
-
-