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

Oracle 觸發器自動生成單據號實戰:前綴+年月+流水號格式

     編輯:Oracle 教學

Oracle 觸發器自動生成單據號實戰:前綴+年月+流水號格式

通過 BEFORE INSERT 行級觸發器,結合配置表取前綴、當前月份、本月最大流水號,自動生成格式為 GXCB_20241100001 的單據號,含完整代碼與邏輯解析。

觸發器完整代碼

CREATE OR REPLACE TRIGGER trg_kc_sprk_i
BEFORE INSERT ON kc_sprk
FOR EACH ROW
DECLARE
  v_scbh   VARCHAR2(40);  -- 前綴
  i_count  NUMBER;        -- 本月流水號
  i_for    NUMBER;        -- 循環變量
BEGIN
  -- 1. 從單據編碼規則表獲取前綴 (規則 ID=8)
  SELECT t.bhqz INTO v_scbh FROM xt_djbhgz t WHERE t.gzid = 8;
  -- 若無配置表,可直接硬編碼: v_scbh := 'GXCB_';

  -- 2. 計算本月已有單據數 + 1
  SELECT COUNT(1) + 1 INTO i_count
  FROM kc_sprk j
  WHERE j.xzsj >= TRUNC(SYSDATE, 'MM');  -- 本月第一天 00:00:00

  -- 3. 組裝前綴 + 年月 (yyyymm)
  v_scbh := v_scbh || TO_CHAR(SYSDATE, 'YYYYMM');  -- 'GXCB_202411'

  -- 4. 補齊流水號至固定 5 位 (不足前補 0)
  FOR i_for IN 1 .. 5 - LENGTH(i_count) LOOP
    v_scbh := v_scbh || '0';
  END LOOP;

  -- 5. 最終單據號賦值給新行
  :NEW.rk_djh := v_scbh || i_count;
END trg_kc_sprk_i;

生成效果示例

-- 假設前綴 GXCB_,11 月第 1,2,3 筆
GXCB_20241100001
GXCB_20241100002
GXCB_20241100003

邏輯解析與優化點

步驟邏輯潛在問題優化建議
取前綴查配置表 XT_DJBH_GZ查表開銷、配置變更需重編譯改用 SYS_CONTEXT / 全局變量 / Result Cache 函數緩存前綴
計算流水COUNT(*) + 1 掃描本月數據大表全掃、併發下重複風險改用 序列 + 獨立表存儲月份狀態 或 DBMS_SQLTUNE 緩存
補零循環PL/SQL 循環拼接效率低LPAD(i_count, 5, '0') 或 TO_CHAR(i_count, 'FM00000')
併發安全無鎖機制高併發下極大概率產生重複單據號加 SELECT ... FOR UPDATE 鎖定統計行,或用序列保證唯一性

高併發安全版 (序列 + 月份重置表)

-- 1. 創建序列 (不循環, 不緩存)
CREATE SEQUENCE seq_kc_sprk NOCACHE NOCYCLE;

-- 2. 月份重置記錄表
CREATE TABLE kc_sprk_seq_ctrl (
  yyyymm   VARCHAR2(6) PRIMARY KEY,
  base_val NUMBER DEFAULT 0  -- 該月序列起始基數
);

-- 3. 觸發器邏輯 (簡化)
:NEW.rk_djh := v_prefix || TO_CHAR(SYSDATE,'YYYYMM') ||
               LPAD(seq_kc_sprk.NEXTVAL - base_val, 5, '0');
-- 每月首筆插入 kc_sprk_seq_ctrl 記錄 base_val = seq.CURRVAL - 1

總結

觸發器生成單據號邏輯直觀,但行級觸發器 + COUNT(*) 掃描 + 無鎖 在高併發下極易重複且性能差。生產系統建議採用 序列 + 月份基數表 或 Redis/應用層號段模式,觸發器僅作為兼容舊系統的過渡方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved