Oracle中金额数字转换为大写汉字

这个版本的函数,解决的问题

  1. 零出现重复或不出现的问题
  2. 当金额只有角或分的显示问题
  3. 金额为整数时,是否想要带 整 字
sql 复制代码
CREATE OR REPLACE FUNCTION NUM_TO_CAPITAL(MONEY IN NUMBER)
  RETURN VARCHAR2
IS
  TYPE STRING_ARRAY IS TABLE OF VARCHAR2(10);
  DIGIT_STR STRING_ARRAY := STRING_ARRAY('零','壹','贰','叁','肆','伍','陆','柒','捌','玖');
  
  V_NUM        VARCHAR2(100);
  V_INT        VARCHAR2(100);
  V_DEC        VARCHAR2(10);
  V_RESULT     VARCHAR2(300) := '';
  V_SECTION    VARCHAR2(4);
  V_SEC_RES    VARCHAR2(50) := '';
  V_I          NUMBER := 0;
  V_HAS_NUM    BOOLEAN;
  V_IS_OVER_WAN BOOLEAN := FALSE; -- 是否 >= 万元
BEGIN
  -- 1. 空值处理
  IF MONEY IS NULL THEN
    RETURN '';
  END IF;

  -- 2. 负数处理
  IF MONEY < 0 THEN
    RETURN '负' || NUM_TO_CAPITAL(ABS(MONEY));
  END IF;

  -- 3. 金额上限校验
  IF MONEY >= POWER(10,16) THEN
    RAISE_APPLICATION_ERROR(-20001, '金额超出转换范围(最大支持9999999999999999.99)');
  END IF;

  -- 4. 格式化拆分整数、小数
  V_NUM := TO_CHAR(ROUND(MONEY, 2), 'FM9999999999999990.00');
  V_INT := SUBSTR(V_NUM, 1, INSTR(V_NUM, '.') - 1);
  V_DEC := SUBSTR(V_NUM, INSTR(V_NUM, '.') + 1);

  -- 5. 整数部分为0时,不拼接"零元",直接处理小数
  IF V_INT != '0' THEN
    WHILE LENGTH(V_INT) > 0 LOOP
      IF LENGTH(V_INT) > 4 THEN
        V_SECTION := SUBSTR(V_INT, LENGTH(V_INT)-3, 4);
        V_INT     := SUBSTR(V_INT, 1, LENGTH(V_INT)-4);
      ELSE
        V_SECTION := LPAD(V_INT, 4, '0');
        V_INT     := '';
      END IF;

      V_SEC_RES := '';
      V_HAS_NUM := FALSE;

      -- 逐位转换:仟、佰、拾、个
      FOR J IN 1..4 LOOP
        DECLARE
          D  CHAR(1) := SUBSTR(V_SECTION, J, 1);
          U  VARCHAR2(2) := CASE J WHEN 1 THEN '仟' WHEN 2 THEN '佰' WHEN 3 THEN '拾' ELSE '' END;
        BEGIN
          IF D != '0' THEN
            IF V_SEC_RES IS NOT NULL AND SUBSTR(V_SECTION, J-1, 1) = '0' THEN
              V_SEC_RES := V_SEC_RES || '零';
            END IF;
            V_SEC_RES := V_SEC_RES || DIGIT_STR(TO_NUMBER(D)+1) || U;
            V_HAS_NUM := TRUE;
          END IF;
        END;
      END LOOP;

      -- 追加单位:万、亿、万亿
      IF V_HAS_NUM THEN
        CASE V_I
          WHEN 1 THEN 
            V_SEC_RES := V_SEC_RES || '万'; 
            V_IS_OVER_WAN := TRUE;
          WHEN 2 THEN 
            V_SEC_RES := V_SEC_RES || '亿'; 
            V_IS_OVER_WAN := TRUE;
          WHEN 3 THEN 
            V_SEC_RES := V_SEC_RES || '万亿'; 
            V_IS_OVER_WAN := TRUE;
          ELSE NULL;
        END CASE;
        V_RESULT := V_SEC_RES || V_RESULT;
      ELSIF V_I = 1 AND V_RESULT IS NOT NULL THEN
        IF SUBSTR(V_RESULT, 1, 1) != '零' THEN
          V_RESULT := '零' || V_RESULT;
        END IF;
      END IF;

      V_I := V_I + 1;
    END LOOP;

    -- 整数部分收尾
    IF V_RESULT IS NOT NULL THEN
      V_RESULT := V_RESULT || '元';
    END IF;
  END IF;

  -- 6. 小数部分处理
  IF V_DEC != '00' THEN
    -- 角
    IF SUBSTR(V_DEC,1,1) != '0' THEN
      V_RESULT := V_RESULT || DIGIT_STR(TO_NUMBER(SUBSTR(V_DEC,1,1))+1) || '角';
    ELSIF SUBSTR(V_DEC,2,1) != '0' AND V_RESULT IS NOT NULL THEN
      V_RESULT := V_RESULT || '零';
    END IF;
    -- 分
    IF SUBSTR(V_DEC,2,1) != '0' THEN
      V_RESULT := V_RESULT || DIGIT_STR(TO_NUMBER(SUBSTR(V_DEC,2,1))+1) || '分';
    END IF;
  ELSE
    -- 核心规则:只有 ≥ 万元 且无小数时才加"整"
    IF V_RESULT IS NOT NULL AND V_IS_OVER_WAN THEN
      V_RESULT := V_RESULT || '整';
    END IF;
  END IF;

  -- 7. 处理全零金额
  IF V_RESULT IS NULL OR V_RESULT = '' THEN
    RETURN '零元';
  END IF;

  RETURN V_RESULT;
END NUM_TO_CAPITAL;
相关推荐
HackTwoHub1 天前
AI大模型网关存在SQL注入、附 POC 复现、影响版本LiteLLM 1.81.16~1.83.7(CVE-2026-42208)
数据库·人工智能·sql·网络安全·系统安全·网络攻击模型·安全架构
l1t1 天前
DeepSeek总结的DuckLake构建基于 SQL 原生表格式的下一代数据湖仓
数据库·sql
KmSH8umpK1 天前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第八篇
数据库·redis·分布式
TDengine (老段)1 天前
从施工监测到运营预警,桥科院用 TDengine 提升桥梁数据管理能力
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
S1998_1997111609•X1 天前
论mysql国盾shell-sfa犯罪行为集团下的分项工程及反向注入原理尐深度纳米算法下的鐌檵鄐鉎行为
网络·数据库·网络协议·百度·开闭原则
KmSH8umpK1 天前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第七篇
数据库·redis·分布式
BU摆烂会噶1 天前
【LangGraph】持久化实现的三大能力——时间旅行
数据库·人工智能·python·postgresql·langchain
l1t1 天前
DeepSeek总结的DuckLake 入门
数据库
Joseph Cooper1 天前
RAG 与 AI Agent:智能体真的需要检索增强生成吗?
数据库·人工智能·ai·agent·rag·上下文工程
light blue bird1 天前
主子端台二分法任务汇总组件
前端·数据库·.net·桌面端winform