首页 > 代码库 > oracle 处理时间和金额大小写的相关函数集合
oracle 处理时间和金额大小写的相关函数集合
1 CREATE OR REPLACE FUNCTION MONEY_TO_CHINESE(MONEY IN VARCHAR2) 2 RETURN VARCHAR2 IS 3 C_MONEY VARCHAR2(12); 4 M_STRING VARCHAR2(60) := ‘分角圆拾佰仟万拾佰仟亿‘; 5 N_STRING VARCHAR2(40) := ‘壹贰叁肆伍陆柒捌玖‘; 6 B_STRING VARCHAR2(80); 7 N CHAR; 8 LEN NUMBER(3); 9 I NUMBER(3); 10 TMP NUMBER(12); 11 IS_ZERO BOOLEAN; 12 Z_COUNT NUMBER(3); 13 L_MONEY NUMBER; 14 L_SIGN VARCHAR2(10); 15 BEGIN 16 L_MONEY := ABS(MONEY); 17 18 IF MONEY < 0 THEN 19 L_SIGN := ‘负‘; 20 ELSE 21 L_SIGN := ‘‘; 22 END IF; 23 24 TMP := ROUND(L_MONEY, 2) * 100; 25 C_MONEY := RTRIM(LTRIM(TO_CHAR(TMP, ‘999999999999‘))); 26 LEN := LENGTH(C_MONEY); 27 IS_ZERO := TRUE; 28 Z_COUNT := 0; 29 I := 0; 30 31 WHILE I < LEN LOOP 32 I := I + 1; 33 N := SUBSTR(C_MONEY, I, 1); 34 35 IF N = ‘0‘ THEN 36 IF LEN - I = 6 OR LEN - I = 2 OR LEN = I THEN 37 IF IS_ZERO THEN 38 B_STRING := SUBSTR(B_STRING, 1, LENGTH(B_STRING) - 1); 39 IS_ZERO := FALSE; 40 END IF; 41 42 IF LEN - I = 6 THEN 43 B_STRING := B_STRING || ‘万‘; 44 END IF; 45 46 IF LEN - I = 2 THEN 47 B_STRING := B_STRING || ‘圆‘; 48 END IF; 49 50 IF LEN = I THEN 51 B_STRING := B_STRING || ‘整‘; 52 END IF; 53 54 Z_COUNT := 0; 55 ELSE 56 IF Z_COUNT = 0 THEN 57 B_STRING := B_STRING || ‘零‘; 58 IS_ZERO := TRUE; 59 END IF; 60 61 Z_COUNT := Z_COUNT + 1; 62 END IF; 63 ELSE 64 B_STRING := B_STRING || SUBSTR(N_STRING, TO_NUMBER(N), 1) || 65 SUBSTR(M_STRING, LEN - I + 1, 1); 66 Z_COUNT := 0; 67 IS_ZERO := FALSE; 68 END IF; 69 END LOOP; 70 71 B_STRING := L_SIGN || B_STRING; 72 RETURN B_STRING; 73 EXCEPTION 74 WHEN OTHERS THEN 75 RETURN(SQLERRM); 76 END; 77 78 79 CREATE OR REPLACE FUNCTION TO_UPPER_NUM 80 ( 81 P_NUM IN NUMBER DEFAULT NULL, 82 P_ROUND NUMBER DEFAULT 2, --输出要保留的小数位数 83 P_MONTH NUMBER DEFAULT 1 --输出不为月份或者日时 84 ) 85 RETURN VARCHAR2 86 IS 87 /** 88 *阿拉伯数字转化为大写汉字的函数 89 *输入参数转换前的数字,要保留的小数位数(4舍5入可以不输入,默认为小数点后2位) 90 *输出参数为转化后的大写数字 91 *支持小数点和负数,但数字整数部分不能超过16位 92 *支持转换月份和日期,如 SELECT TO_UPPER_NUM(‘31‘,‘3‘,‘2‘) FROM DUAL 93 *--日期例子(年份的转换见另一个函数) 94 * SELECT TO_UPPER_YEAR(TO_CHAR(SYSDATE,‘YYYY‘)) || ‘年‘ || 95 * TO_UPPER_NUM(TO_CHAR(SYSDATE,‘MM‘),‘2‘,‘2‘) || ‘月‘ || 96 * TO_UPPER_NUM(TO_CHAR(SYSDATE,‘DD‘),‘2‘,‘2‘) || ‘日‘ 97 * FROM DUAL ; 98 *--货币例子(截取小数点后两位,四舍五入) 99 * SELECT TO_UPPER_NUM(1234.564) FROM dual ;100 */101 RESULT NVARCHAR2(100) := ‘‘; --返回大写汉字字符串102 NUM_ROUND NVARCHAR2(100) := TO_CHAR(ABS(ROUND(P_NUM, P_ROUND))); --转换数字为小数点后p_round位的字符(正数)103 NUM_LEFT NVARCHAR2(100); --小数点左边的数字104 NUM_RIGHT NVARCHAR2(100); --小数点右边的数字105 STR1 NCHAR(10) := ‘零壹贰叁肆伍陆柒捌玖‘; --数字大写106 STR2 NCHAR(16) := ‘点拾佰仟万拾佰仟亿拾佰仟万拾佰仟‘; --数字位数(从低至高)107 STR3 NCHAR(10) := ‘〇一二三四五六七八九‘; --月份数字大写108 STR4 NCHAR(16) := ‘点十佰仟万拾佰仟亿拾佰仟万拾佰仟‘; --数字位数(从低至高)109 NUM_PRE NUMBER(1) := 1; --前一位上的数字110 NUM_CURRENT NUMBER(1); --当前位上的数字111 NUM_COUNT NUMBER := 0; --当前数字位数112 BEGIN113 --转换数字为NULL时,返回NULL114 IF P_NUM IS NULL THEN115 RETURN NULL;116 END IF;117 --如果要转换月份或者日时,则替换临时变量118 IF P_MONTH <> 1 THEN119 STR1 := STR3;120 STR2 := STR4;121 END IF;122 --取得小数点左边的数字123 SELECT TO_CHAR(NVL(SUBSTR(TO_CHAR(NUM_ROUND),124 1,125 DECODE(INSTR(TO_CHAR(NUM_ROUND), ‘.‘),126 0,127 LENGTH(NUM_ROUND),128 INSTR(TO_CHAR(NUM_ROUND), ‘.‘) - 1)),129 0))130 INTO NUM_LEFT131 FROM DUAL;132 --取得小数点右边的数字133 SELECT SUBSTR(TO_CHAR(NUM_ROUND),134 DECODE(INSTR(TO_CHAR(NUM_ROUND), ‘.‘),135 0,136 LENGTH(NUM_ROUND) + 1,137 INSTR(TO_CHAR(NUM_ROUND), ‘.‘) + 1),138 P_ROUND)139 INTO NUM_RIGHT140 FROM DUAL;141 --数字整数部分超过16位时.采用从低至高的算法,先处理小数点左边的数字142 IF LENGTH(NUM_LEFT) > 16 THEN143 RETURN ‘**********‘;144 END IF;145 FOR I IN REVERSE 1 .. LENGTH(NUM_LEFT) LOOP146 --(从低至高)147 NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_LEFT, I, 1)); --当前位上的数字148 NUM_COUNT := NUM_COUNT + 1; --当前数字位数149 --当前位上数字不为0按正常处理150 IF NUM_CURRENT > 0 THEN151 --如果转换数字最高位是十位,转换后不需要前面的壹,如月份12转换后为拾贰,则152 IF NUM_CURRENT = 1 AND P_MONTH <> 1 AND NUM_COUNT = 2 THEN153 RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;154 STR1 := STR3;155 ELSE156 RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1)157 ||SUBSTR(STR2, NUM_COUNT, 1)158 || RESULT;159 END IF;160 ELSE161 --当前位上数字为0时162 IF MOD(NUM_COUNT - 1, 4) = 0 THEN163 --当前位是点、万或亿时164 RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;165 NUM_PRE := 0; --点、万,亿前不准加零166 END IF;167 IF NUM_PRE > 0 OR LENGTH(NUM_LEFT) = 1 THEN168 --上一位数字不为0或只有个位时169 RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1) || RESULT;170 END IF;171 END IF;172 NUM_PRE := NUM_CURRENT;173 END LOOP;174 --再处理小数点右边的数字175 IF LENGTH(NUM_RIGHT) > 0 THEN176 FOR I IN 1 .. LENGTH(NUM_RIGHT) LOOP177 --(从高至低)178 NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_RIGHT, I, 1)); --当前位上的数字179 RESULT := RESULT || SUBSTR(STR1, NUM_CURRENT + 1, 1);180 END LOOP;181 ELSE182 RESULT := REPLACE(RESULT, ‘点‘, ‘‘); --无小数时去掉点183 END IF;184 --转换数字是负数时185 IF P_NUM < 0 THEN186 RESULT := ‘负‘ || RESULT;187 END IF;188 RETURN RESULT;189 EXCEPTION190 WHEN OTHERS THEN191 DBMS_OUTPUT.PUT_LINE(SQLERRM);192 RETURN ‘‘;193 END;194 195 196 CREATE OR REPLACE FUNCTION TO_UPPER_YEAR(YEAR_IN IN VARCHAR2)197 RETURN VARCHAR2198 /**199 *年转化为大写汉字的函数 如将2008转换为二〇〇八200 *月份和日期转换的可以调用 TO_UPPER_NUM 函数201 *如SELECT TO_UPPER_NUM(‘21‘,‘2‘,‘2‘) FROM DUAL202 *查询系统大写年月日如下:203 *SELECT TO_UPPER_YEAR(TO_CHAR(SYSDATE,‘YYYY‘)) || ‘年‘ ||204 * TO_UPPER_NUM(TO_CHAR(SYSDATE,‘MM‘),‘2‘,‘2‘) || ‘月‘ ||205 * TO_UPPER_NUM(TO_CHAR(SYSDATE,‘DD‘),‘2‘,‘2‘) || ‘日‘ SJ206 *FROM DUAL207 */208 IS209 TEMP VARCHAR2(32767);210 RESULT VARCHAR2(32767);211 STR VARCHAR2(32767) := ‘〇一二三四五六七八九‘;212 BEGIN213 IF YEAR_IN IS NULL THEN214 RETURN NULL;215 END IF;216 FOR I IN 1 .. LENGTH(YEAR_IN)217 LOOP218 SELECT SUBSTR(STR, SUBSTR(YEAR_IN,I, 1) + 1, 1)219 INTO TEMP220 FROM DUAL;221 RESULT := RESULT || TEMP;222 END LOOP;223 RETURN RESULT;224 EXCEPTION225 WHEN OTHERS THEN226 DBMS_OUTPUT.PUT_LINE(SQLERRM);227 RETURN ‘‘;228 END;
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。