/**PageBeginHtml Block Begin **/ /***自定义返回顶部小火箭***/ /*生成博客目录的JS 开始*/ /*生成博客目录的JS 结束*/

oracle实现阿拉伯数字转化为大写汉字的函数


oracle实现阿拉伯数字转化为大写汉字的函数

今天工作中遇到了要改货币金额转换为大写显示的需求,找到了一些前辈们的代码,总结了一下贴出来,以备以后查看学习使用.

 

1.专门用于转化年份的函数TO_UPPER_YEAR.


  1. CREATE OR REPLACE FUNCTION TO_UPPER_YEAR(YEAR_IN IN VARCHAR2)
  2. RETURN VARCHAR2
  3. /**
  4. *年转化为大写汉字的函数 如将2008转换为二〇〇八
  5. *月份和日期转换的可以调用 TO_UPPER_NUM 函数
  6. *如SELECT TO_UPPER_NUM('21','2','2') FROM DUAL
  7. *查询系统大写年月日如下:
  8. *SELECT TO_UPPER_YEAR(TO_CHAR(SYSDATE,'YYYY')) || '年' ||
  9. * TO_UPPER_NUM(TO_CHAR(SYSDATE,'MM'),'2','2') || '月' ||
  10. * TO_UPPER_NUM(TO_CHAR(SYSDATE,'DD'),'2','2') || '日' SJ
  11. *FROM DUAL
  12. */
  13. IS
  14. TEMP VARCHAR2(32767);
  15. RESULT VARCHAR2(32767);
  16. STR VARCHAR2(32767) := '〇一二三四五六七八九';
  17. BEGIN
  18. IF YEAR_IN IS NULL THEN
  19. RETURN NULL;
  20. END IF;
  21. FOR I IN 1 .. LENGTH(YEAR_IN)
  22. LOOP
  23. SELECT SUBSTR(STR, SUBSTR(YEAR_IN,I, 1) + 1, 1)
  24. INTO TEMP
  25. FROM DUAL;
  26. RESULT := RESULT || TEMP;
  27. END LOOP;
  28. RETURN RESULT;
  29. EXCEPTION
  30. WHEN OTHERS THEN
  31. DBMS_OUTPUT.PUT_LINE(SQLERRM);
  32. RETURN '';
  33. END;
 

2.用于阿拉伯数字转化为大写汉字的函数TO_UPPER_NUM.


  1. CREATE OR REPLACE FUNCTION TO_UPPER_NUM
  2. (
  3. P_NUM IN NUMBER DEFAULT NULL,
  4. P_ROUND NUMBER DEFAULT 2, --输出要保留的小数位数
  5. P_MONTH NUMBER DEFAULT 1 --输出不为月份或者日时,当此参数输入不为1时,返回值为大写(非汉字)数字
  6. )
  7. RETURN NVARCHAR2
  8. IS
  9. /**
  10. *阿拉伯数字转化为大写汉字的函数
  11. *输入参数转换前的数字,要保留的小数位数(4舍5入可以不输入,默认为小数点后2位)
  12. *输出参数为转化后的大写数字
  13. *支持小数点和负数,但数字整数部分不能超过16位
  14. *支持转换月份和日期,如 SELECT TO_UPPER_NUM('31','3','2') FROM DUAL
  15. *--日期例子(年份的转换见另一个函数)
  16. * SELECT TO_UPPER_YEAR(TO_CHAR(SYSDATE,'YYYY')) || '年' ||
  17. * TO_UPPER_NUM(TO_CHAR(SYSDATE,'MM'),'2','2') || '月' ||
  18. * TO_UPPER_NUM(TO_CHAR(SYSDATE,'DD'),'2','2') || '日'
  19. * FROM DUAL ;
  20. *--货币例子(截取小数点后两位,四舍五入)
  21. * SELECT TO_UPPER_NUM(1234.564) FROM dual ;
  22. */
  23. RESULT NVARCHAR2(100) := ''; --返回大写汉字字符串
  24. NUM_ROUND NVARCHAR2(100) := TO_CHAR(ABS(ROUND(P_NUM, P_ROUND))); --转换数字为小数点后p_round位的字符(正数)
  25. NUM_LEFT NVARCHAR2(100); --小数点左边的数字
  26. NUM_RIGHT NVARCHAR2(100); --小数点右边的数字
  27. STR1 NCHAR(10) := '零壹贰叁肆伍陆柒捌玖'; --数字大写
  28. STR2 NCHAR(16) := '点拾佰仟万拾佰仟亿拾佰仟万拾佰仟'; --数字位数(从低至高)
  29. STR3 NCHAR(10) := '〇一二三四五六七八九'; --月份数字大写
  30. STR4 NCHAR(16) := '点十佰仟万拾佰仟亿拾佰仟万拾佰仟'; --数字位数(从低至高)
  31. NUM_PRE NUMBER(1) := 1; --前一位上的数字
  32. NUM_CURRENT NUMBER(1); --当前位上的数字
  33. NUM_COUNT NUMBER := 0; --当前数字位数
  34. BEGIN
  35. --转换数字为NULL时,返回NULL
  36. IF P_NUM IS NULL THEN
  37. RETURN NULL;
  38. END IF;
  39. --如果要转换月份或者日时,则替换临时变量
  40. IF P_MONTH <> 1 THEN
  41. STR1 := STR3;
  42. STR2 := STR4;
  43. END IF;
  44. --取得小数点左边的数字
  45. SELECT TO_CHAR(NVL(SUBSTR(TO_CHAR(NUM_ROUND),
  46. 1,
  47. DECODE(INSTR(TO_CHAR(NUM_ROUND), '.'),
  48. 0,
  49. LENGTH(NUM_ROUND),
  50. INSTR(TO_CHAR(NUM_ROUND), '.') - 1)),
  51. 0))
  52. INTO NUM_LEFT
  53. FROM DUAL;
  54. --取得小数点右边的数字
  55. SELECT SUBSTR(TO_CHAR(NUM_ROUND),
  56. DECODE(INSTR(TO_CHAR(NUM_ROUND), '.'),
  57. 0,
  58. LENGTH(NUM_ROUND) + 1,
  59. INSTR(TO_CHAR(NUM_ROUND), '.') + 1),
  60. P_ROUND)
  61. INTO NUM_RIGHT
  62. FROM DUAL;
  63. --数字整数部分超过16位时.采用从低至高的算法,先处理小数点左边的数字
  64. IF LENGTH(NUM_LEFT) > 16 THEN
  65. RETURN '**********';
  66. END IF;
  67. FOR I IN REVERSE 1 .. LENGTH(NUM_LEFT) LOOP
  68. --(从低至高)
  69. NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_LEFT, I, 1)); --当前位上的数字
  70. NUM_COUNT := NUM_COUNT + 1; --当前数字位数
  71. --当前位上数字不为0按正常处理
  72. IF NUM_CURRENT > 0 THEN
  73. --如果转换数字最高位是十位,转换后不需要前面的壹,如月份12转换后为拾贰,则
  74. IF NUM_CURRENT = 1 AND P_MONTH <> 1 AND NUM_COUNT = 2 THEN
  75. RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;
  76. STR1 := STR3;
  77. ELSE
  78. RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1)
  79. ||SUBSTR(STR2, NUM_COUNT, 1)
  80. || RESULT;
  81. END IF;
  82. ELSE
  83. --当前位上数字为0
  84. IF MOD(NUM_COUNT - 1, 4) = 0 THEN
  85. --当前位是点、万或亿时
  86. RESULT := SUBSTR(STR2, NUM_COUNT, 1) || RESULT;
  87. NUM_PRE := 0; --点、万,亿前不准加零
  88. END IF;
  89. IF NUM_PRE > 0 OR LENGTH(NUM_LEFT) = 1 THEN
  90. --上一位数字不为0或只有个位时
  91. RESULT := SUBSTR(STR1, NUM_CURRENT + 1, 1) || RESULT;
  92. END IF;
  93. END IF;
  94. NUM_PRE := NUM_CURRENT;
  95. END LOOP;
  96. --再处理小数点右边的数字
  97. IF LENGTH(NUM_RIGHT) > 0 THEN
  98. FOR I IN 1 .. LENGTH(NUM_RIGHT) LOOP
  99. --(从高至低)
  100. NUM_CURRENT := TO_NUMBER(SUBSTR(NUM_RIGHT, I, 1)); --当前位上的数字
  101. RESULT := RESULT || SUBSTR(STR1, NUM_CURRENT + 1, 1);
  102. END LOOP;
  103. ELSE
  104. RESULT := REPLACE(RESULT, '点', ''); --无小数时去掉点
  105. END IF;
  106. --转换数字是负数时
  107. IF P_NUM < 0 THEN
  108. RESULT := '负' || RESULT;
  109. END IF;
  110. RETURN RESULT;
  111. EXCEPTION
  112. WHEN OTHERS THEN
  113. DBMS_OUTPUT.PUT_LINE(SQLERRM);
  114. RETURN '';
  115. END;

Oracle实现小写金额转换成大写的方法

Oracle实现小写金额转换成大写的方法,代码如下:
CREATE OR REPLACE FUNCTION convert_money(n_LowerMoney IN NUMBER,
 
                                        v_TransType IN NUMBER DEFAULT 1 -- 1: directly translate, 0: read it in words
 
                                        ) RETURN VARCHAR2 AS
 
v_LowerStr VARCHAR2(200); -- 小写金额
 
v_UpperPart VARCHAR2(200);
 
v_UpperStr VARCHAR2(200); -- 大写金额
BEGIN
 
v_LowerStr := LTRIM(RTRIM(TO_CHAR(ROUND(n_LowerMoney, 2),
 
                                   9999999999999.99)));
 
IF SUBSTR(v_LowerStr, 1, 1) = # THEN
 
   RETURN 转换金额超过计算范围(计算范围为 :计算范围为 :0 - 9,
 
                               999,
 
                               999,
 
                               999,
 
                               999.99);
 
END IF;

  FOR I IN 1 .. LENGTH(v_LowerStr) LOOP
 
   SELECT DECODE(SUBSTR(v_LowerStr,LENGTH(v_LowerStr) - I + 1,1),
 
           .,元,0,零, 1,壹, 2,贰, 3,叁, 4,肆,
 
           5,伍, 6,陆, 7,柒, 8,捌, 9,玖)||
 
           DECODE(I,1,分,2,角,3,NULL,4,NULL,5,拾,6,佰,7,仟,8,万,
 
           9,拾,10,佰,11,仟,12,亿,13,拾,14,佰,15,仟,16,万,NULL)
 
           INTO v_UpperPart FROM DUAL;
 

    v_UpperStr := v_UpperPart || v_UpperStr;
 
END LOOP;

  IF v_TransType = 0 then
 
   v_UpperStr := REPLACE(v_UpperStr, 零拾, 零);
 
   v_UpperStr := REPLACE(v_UpperStr, 零佰, 零);
 
   v_UpperStr := REPLACE(v_UpperStr, 零仟, 零);
 
   v_UpperStr := REPLACE(v_UpperStr, 零零零, 零);
 
   v_UpperStr := REPLACE(v_UpperStr, 零零, 零);
 
   v_UpperStr := REPLACE(v_UpperStr, 零角零分, 整);
 
   v_UpperStr := REPLACE(v_UpperStr, 零分, 整);
 
   v_UpperStr := REPLACE(v_UpperStr, 零角, 零);
 
   v_UpperStr := REPLACE(v_UpperStr, 零亿零万零元, 亿元);
 
   v_UpperStr := REPLACE(v_UpperStr, 亿零万零元, 亿元);
 
   v_UpperStr := REPLACE(v_UpperStr, 零亿零万, 亿);
 
   v_UpperStr := REPLACE(v_UpperStr, 零万零元, 万元);
 
   v_UpperStr := REPLACE(v_UpperStr, 万零元, 万元);
 
   v_UpperStr := REPLACE(v_UpperStr, 零亿, 亿);
 
   v_UpperStr := REPLACE(v_UpperStr, 零万, 万);
 
   v_UpperStr := REPLACE(v_UpperStr, 零元, 元);
 
   v_UpperStr := REPLACE(v_UpperStr, 零零, 零);
 
END IF;

  -- 对壹元以下的金额的处理
 
v_UpperStr := LTRIM(LTRIM(LTRIM(LTRIM(v_UpperStr, 元), 零), 角), 分);
 
IF SUBSTR(v_UpperStr, 1, 1) = 整 THEN
 
   v_UpperStr := 零元整;
 
END IF;

  RETURN v_UpperStr;

EXCEPTION
 
WHEN OTHERS THEN
 
   RETURN 发生错误 :|| SQLCODE || --||SQLERRM;
END convert_money;






--

posted @ 2020-11-13 16:36  一品堂.技术学习笔记  阅读(847)  评论(0编辑  收藏  举报