oracle实现阿拉伯数字转化为⼤写汉字的函数今天⼯作中遇到了要改货币⾦额转换为⼤写显⽰的需求,到了⼀些前辈们的代码,总结了⼀下贴出来,以备以后查看学习使⽤.
1.专门⽤于转化年份的函数TO_UPPER_YEAR.
CREATE OR REPLACE FUNCTION TO_UPPER_YEAR(YEAR_IN  IN VARCHAR2)
RETURN VARCHAR2
/**
*年转化为⼤写汉字的函数如将2008转换为⼆〇〇⼋
*⽉份和⽇期转换的可以调⽤ TO_UPPER_NUM 函数
*如SELECT TO_UPPER_NUM('21','2','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') || '⽇'  SJ
*FROM DUAL
*/
IS
TEMP    VARCHAR2(32767);
RESULT  VARCHAR2(32767);
STR      VARCHAR2(32767) := '〇⼀⼆三四五六七⼋九';
BEGIN
IF YEAR_IN IS NULL THEN
RETURN NULL;
END IF;
FOR I IN 1 .. LENGTH(YEAR_IN)
LOOP
SELECT SUBSTR(STR, SUBSTR(YEAR_IN,I, 1) + 1, 1)
INTO TEMP
FROM DUAL;
RESULT := RESULT || TEMP;
END LOOP;
RETURN RESULT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RETURN '';
END;
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时,返回值为⼤写(⾮汉字)数字
)
RETURN  NVARCHAR2
IS
/**
*阿拉伯数字转化为⼤写汉字的函数
*输⼊参数转换前的数字,要保留的⼩数位数(4舍5⼊可以不输⼊,默认为⼩数点后2位)
*输出参数为转化后的⼤写数字
*⽀持⼩数点和负数,但数字整数部分不能超过16位
*⽀持转换⽉份和⽇期,如 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') || '⽇'
*  TO_UPPER_NUM(TO_CHAR(SYSDATE,'DD'),'2','2') || '⽇'
*  FROM DUAL ;
*--货币例⼦(截取⼩数点后两位,四舍五⼊)
*  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;          --当前数字位数
BEGIN
--转换数字为NULL时,返回NULL
IF P_NUM IS NULL THEN
RETURN NULL;
END IF;
--如果要转换⽉份或者⽇时,则替换临时变量
IF P_MONTH <> 1 THEN
STR1 := STR3;
STR2 := STR4;
END IF;
--取得⼩数点左边的数字
SELECT TO_CHAR(NVL(SUBSTR(TO_CHAR(NUM_ROUND),
1,
DECODE(INSTR(TO_CHAR(NUM_ROUND), '.'),
0,
LENGTH(NUM_ROUND),
INSTR(TO_CHAR(NUM_ROUND), '.') - 1)),
0))
INTO NUM_LEFT
FROM DUAL;
--取得⼩数点右边的数字
SELECT SUBSTR(TO_CHAR(NUM_ROUND),
DECODE(INSTR(TO_CHAR(NUM_ROUND), '.'),
0,
LENGTH(NUM_ROUND) + 1,
INSTR(TO_CHAR(NUM_ROUND), '.') + 1),
P_ROUND)
INTO NUM_RIGHT
FROM DUAL;
--数字整数部分超过16位时.采⽤从低⾄⾼的算法,先处理⼩数点左边的数字
IF LENGTH(NUM_LEFT) > 16 THEN
RETURN '**********';
END IF;
FOR I IN REVERSE 1 .. LENGTH(NUM_LEFT) LOOP
--(从低⾄⾼)
NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_LEFT, I, 1)); --当前位上的数字
NUM_COUNT  := NUM_COUNT + 1;                    --当前数字位数
--当前位上数字不为0按正常处理
IF NUM_CURRENT > 0 THEN
--如果转换数字最⾼位是⼗位,转换后不需要前⾯的壹,如⽉份12转换后为拾贰,则
IF NUM_CURRENT = 1 AND P_MONTH <> 1 AND NUM_COUNT = 2 THEN
RESULT :=  SUBSTR(STR2, NUM_COUNT, 1) || RESULT;
STR1 := STR3;
ELSE
RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1)
||SUBSTR(STR2, NUM_COUNT, 1)
|| RESULT;
END IF;
ELSE
--当前位上数字为0时
--当前位上数字为0时
IF MOD(NUM_COUNT - 1, 4) = 0 THEN
-
-当前位是点、万或亿时
RESULT  := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;
NUM_PRE := 0; --点、万,亿前不准加零
END IF;
IF NUM_PRE > 0 OR LENGTH(NUM_LEFT) = 1 THEN
--上⼀位数字不为0或只有个位时
RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1) || RESULT;
END IF;
END IF;
NUM_PRE := NUM_CURRENT;
END LOOP;
-
-再处理⼩数点右边的数字
IF LENGTH(NUM_RIGHT) > 0 THEN
FOR I IN 1 .. LENGTH(NUM_RIGHT) LOOP
oracle四舍五入--(从⾼⾄低)
NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_RIGHT, I, 1)); --当前位上的数字      RESULT      := RESULT || SUBSTR(STR1, NUM_CURRENT + 1, 1);
END LOOP;
ELSE
RESULT := REPLACE(RESULT, '点', '');                --⽆⼩数时去掉点
END IF;
--转换数字是负数时
IF P_NUM < 0 THEN
RESULT := '负' || RESULT;
END IF;
RETURN RESULT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RETURN '';
END;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。