zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    scanf与scanf_s的区别
    C语言输出时的各种%
    Windows下配置OpenGL环境
    C#高级进阶--重写函数
    Linux下安装国际版QQ (转)
    Linux Vim不明原因卡死解决办法
    iCamera App Kit 使用说明
    usb2.0高速视频采集之68013A寄存器配置说明
    iSensor APP 之 摄像头调试 OV5642 续集2
    iSensor APP 之 摄像头调试 OV9655 测试之二
  • 原文地址:https://www.cnblogs.com/wenpeng/p/3881237.html
Copyright © 2011-2022 走看看