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 BEGIN 113 --转换数字为NULL时,返回NULL 114 IF P_NUM IS NULL THEN 115 RETURN NULL; 116 END IF; 117 --如果要转换月份或者日时,则替换临时变量 118 IF P_MONTH <> 1 THEN 119 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_LEFT 131 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_RIGHT 140 FROM DUAL; 141 --数字整数部分超过16位时.采用从低至高的算法,先处理小数点左边的数字 142 IF LENGTH(NUM_LEFT) > 16 THEN 143 RETURN ‘**********‘; 144 END IF; 145 FOR I IN REVERSE 1 .. LENGTH(NUM_LEFT) LOOP 146 --(从低至高) 147 NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_LEFT, I, 1)); --当前位上的数字 148 NUM_COUNT := NUM_COUNT + 1; --当前数字位数 149 --当前位上数字不为0按正常处理 150 IF NUM_CURRENT > 0 THEN 151 --如果转换数字最高位是十位,转换后不需要前面的壹,如月份12转换后为拾贰,则 152 IF NUM_CURRENT = 1 AND P_MONTH <> 1 AND NUM_COUNT = 2 THEN 153 RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT; 154 STR1 := STR3; 155 ELSE 156 RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1) 157 ||SUBSTR(STR2, NUM_COUNT, 1) 158 || RESULT; 159 END IF; 160 ELSE 161 --当前位上数字为0时 162 IF MOD(NUM_COUNT - 1, 4) = 0 THEN 163 --当前位是点、万或亿时 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 THEN 168 --上一位数字不为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 THEN 176 FOR I IN 1 .. LENGTH(NUM_RIGHT) LOOP 177 --(从高至低) 178 NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_RIGHT, I, 1)); --当前位上的数字 179 RESULT := RESULT || SUBSTR(STR1, NUM_CURRENT + 1, 1); 180 END LOOP; 181 ELSE 182 RESULT := REPLACE(RESULT, ‘点‘, ‘‘); --无小数时去掉点 183 END IF; 184 --转换数字是负数时 185 IF P_NUM < 0 THEN 186 RESULT := ‘负‘ || RESULT; 187 END IF; 188 RETURN RESULT; 189 EXCEPTION 190 WHEN OTHERS THEN 191 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 VARCHAR2 198 /** 199 *年转化为大写汉字的函数 如将2008转换为二〇〇八 200 *月份和日期转换的可以调用 TO_UPPER_NUM 函数 201 *如SELECT TO_UPPER_NUM(‘21‘,‘2‘,‘2‘) FROM DUAL 202 *查询系统大写年月日如下: 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‘) || ‘日‘ SJ 206 *FROM DUAL 207 */ 208 IS 209 TEMP VARCHAR2(32767); 210 RESULT VARCHAR2(32767); 211 STR VARCHAR2(32767) := ‘〇一二三四五六七八九‘; 212 BEGIN 213 IF YEAR_IN IS NULL THEN 214 RETURN NULL; 215 END IF; 216 FOR I IN 1 .. LENGTH(YEAR_IN) 217 LOOP 218 SELECT SUBSTR(STR, SUBSTR(YEAR_IN,I, 1) + 1, 1) 219 INTO TEMP 220 FROM DUAL; 221 RESULT := RESULT || TEMP; 222 END LOOP; 223 RETURN RESULT; 224 EXCEPTION 225 WHEN OTHERS THEN 226 DBMS_OUTPUT.PUT_LINE(SQLERRM); 227 RETURN ‘‘; 228 END;