資料表主鍵需要自動遞增,Oracle 12c 前無原生 Identity Column,標準做法是 Sequence + Row-Level Trigger 組合。
CREATE SEQUENCE LZEAM_SP_LOOP_EQ_SEQ
MINVALUE 1
INCREMENT BY 1
START WITH 1
NOCACHE
NOCYCLE;
NOCACHE 確保序列值不會因實例重啟而跳號(效能稍降),NOCYCLE 避免達到上限後循環。
SELECT LZEAM_SP_LOOP_EQ_SEQ.NEXTVAL FROM DUAL;
CREATE OR REPLACE TRIGGER LZEAM.LZEAM_SP_LOOP_EQ_TRIGGER
BEFORE INSERT ON SP_LOOP_EQ
FOR EACH ROW
BEGIN
SELECT LZEAM.LZEAM_SP_LOOP_EQ_SEQ.NEXTVAL
INTO :NEW.LOOP_EQ_CODE
FROM DUAL;
END;
/
關鍵點:
BEFORE INSERT:在寫入前填充主鍵FOR EACH ROW:逐行觸發,確保每筆新資料都取號:NEW.LOOP_EQ_CODE:直接指派給新資料列的主鍵欄位-- 查看當前使用者觸發器
SELECT * FROM USER_TRIGGERS;
-- 停用/啟用特定觸發器
ALTER TRIGGER LZEAM_SP_LOOP_EQ_TRIGGER DISABLE;
ALTER TRIGGER LZEAM_SP_LOOP_EQ_TRIGGER ENABLE;
-- 停用/啟用資料表所有觸發器
ALTER TABLE SP_LOOP_EQ DISABLE ALL TRIGGERS;
ALTER TABLE SP_LOOP_EQ ENABLE ALL TRIGGERS;
12c 起可直接定義:
CREATE TABLE t (
id NUMBER GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(100)
);
優點:無需序列與觸發器,效能更好,支援 GENERATED BY DEFAULT ON NULL 允許手動指定值。
SEQ_<Schema>_<Table>_<Column> 如 SEQ_LZEAM_SP_LOOP_EQ_LOOP_EQ_CODETRG_<Table>_BI_<Column> 如 TRG_SP_LOOP_EQ_BI_LOOP_EQ_CODECACHE 1000 減少序列鎖競爭| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| 主鍵重複 | 序列 CYCLE 或手動插入衝突 | 檢查 NOCYCLE、業務端勿手動指定主鍵 |
| 主鍵跳號 | 序列 CACHE、交易回滾、實例重啟 | 屬正常行為,不可避免;若不可接受改用 NOCACHE |
| 觸發器不生效 | 觸發器停用、權限不足、DDL 導致失效 | 檢查 USER_TRIGGERS.STATUS、重新編譯 |