首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

業務系統金額精度處理:四捨五入、捨去、進位的靈活實作(Oracle PL/SQL)

     編輯:關於SqlServer

需求背景

不同客戶對金額小數位處理規則不一:有的精確到元、角、分;尾數處理有「四捨五入」、「全捨(無條件捨去)」、「全入(無條件進位)」。需建立可配置的統一處理函數。

設定表設計

CREATE TABLE rounding_rules (
    rule_id       NUMBER(1) PRIMARY KEY,           -- 規則 ID
    amount_dot    NUMBER(4,2) DEFAULT 0.01,        -- 精度:1=元, 0.1=角, 0.01=分
    rounding_mode NUMBER(1)                        -- 9=全捨, 0=全入, 4=四捨五入
);

核心處理函數

CREATE OR REPLACE FUNCTION get_real_amount (
    p_rule_id   IN NUMBER,
    p_amount    IN NUMBER
) RETURN NUMBER IS
    v_amount_dot   VARCHAR2(5);
    v_keep         NUMBER;
    v_rounding     NUMBER;
    v_result       NUMBER := 0;
BEGIN
    -- 讀取規則
    SELECT amount_dot, NVL(rounding_mode, 0)
    INTO   v_amount_dot, v_rounding
    FROM   rounding_rules
    WHERE  rule_id = p_rule_id;

    -- 計算保留小數位數(如 0.01 → 2 位)
    v_keep := LENGTH(v_amount_dot) - INSTR(v_amount_dot, '.');

    -- 全捨(無條件捨去)
    IF v_rounding = 9 THEN
        v_result := TRUNC(p_amount, v_keep);
    END IF;

    -- 四捨五入
    IF v_rounding = 4 THEN
        v_result := ROUND(p_amount, v_keep);
    END IF;

    -- 全入(無條件進位)
    IF v_rounding = 0 THEN
        v_result := TRUNC(p_amount, v_keep);
        -- 若截斷後不等於原值,進一個精度單位
        IF v_result <> p_amount THEN
            v_result := v_result + TO_NUMBER(v_amount_dot);
        END IF;
    END IF;

    RETURN v_result;

EXCEPTION
    WHEN OTHERS THEN RETURN p_amount;  -- 異常時回傳原值
END get_real_amount;
/

使用範例

-- 規則:精確到分(0.01),四捨五入(4)
INSERT INTO rounding_rules VALUES (1, 0.01, 4);

SELECT get_real_amount(1, 123.456) FROM dual;  -- 123.46
SELECT get_real_amount(1, 123.454) FROM dual;  -- 123.45

-- 規則:精確到角(0.1),全入(0)
INSERT INTO rounding_rules VALUES (2, 0.1, 0);
SELECT get_real_amount(2, 123.41) FROM dual;   -- 123.5

關鍵點總結

  • 以 amount_dot 字串長度推算保留位數,避免硬編碼。
  • TRUNC 作為基礎操作,配合條件判斷實現三種模式。
  • 例外處理採「失效安全」:異常時回傳原值,避免業務中斷。
  • 可擴充支援更多模式(如銀行家捨入、五捨六入等)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved