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 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;

 

posted @ 2014-07-31 17:02  文鹏  阅读(576)  评论(0编辑  收藏  举报