Oracle 設計哲學強調序列對象獨立於表,支援多表共享、緩存、循環、順序/無序等豐富屬性。12c 引入 IDENTITY 列(語法糖),底層仍由 Sequence 實現。
CREATE TABLE test_table (
id NUMBER NOT NULL, -- 自增主鍵
name VARCHAR2(40)
);
CREATE SEQUENCE seq_test_table
MINVALUE 1
MAXVALUE 999999999999999999999999999
INCREMENT BY 1
START WITH 1
CACHE 20
NOORDER
NOCYCLE;
CACHE 20:SGA 中預分配 20 個值,減少字典鎖爭用,RAC 環境建議 NOORDER(不保證跨實例絕對順序)提升性能。NOCYCLE:達到最大值不循環,防止主鍵衝突。CREATE OR REPLACE TRIGGER trg_test_table_bir
BEFORE INSERT ON test_table
FOR EACH ROW
BEGIN
SELECT seq_test_table.NEXTVAL INTO :NEW.id FROM dual;
END;
/
BEFORE INSERT:在行寫入前賦值。FOR EACH ROW:行級觸發,每行執行一次。:NEW.id:引用新行的 id 列。INSERT INTO test_table (name) VALUES ('Alice');
INSERT INTO test_table (name) VALUES ('Bob');
INSERT INTO test_table (name) VALUES ('Charlie');
SELECT * FROM test_table;
-- ID | NAME
-- 1 | Alice
-- 2 | Bob
-- 3 | Charlie
CREATE TABLE test_table_new (
id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1 CACHE 20),
name VARCHAR2(40)
);
-- 或允許手動指定值(GENERATED BY DEFAULT)
CREATE TABLE test_table_flex (
id NUMBER GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
name VARCHAR2(40)
);
GENERATED ALWAYS:插入時不可指定 ID,違規報 ORA-32795。GENERATED BY DEFAULT:插入時可選指定 ID,未指定則自動取序列值。ISEQ$$_XXXXX,可通過 USER_TAB_IDENTITY_COLS 查詢。CREATE SEQUENCE seq_test;
CREATE TABLE test_table_simple (
id NUMBER DEFAULT ON NULL seq_test.NEXTVAL NOT NULL,
name VARCHAR2(40)
);
ON NULL:當插入值為 NULL 時才取序列值,允許顯式指定 ID。-- 手動指定 ID = 100 插入
INSERT INTO test_table (id, name) VALUES (100, 'Manual');
-- 同步序列到 > 100
DECLARE
v_curr NUMBER;
BEGIN
SELECT seq_test_table.NEXTVAL INTO v_curr FROM dual; -- 先取一個
WHILE v_curr <= 100 LOOP
SELECT seq_test_table.NEXTVAL INTO v_curr FROM dual; -- 循環推進
END LOOP;
END;
/
-- 或 18c+ 一條語句
ALTER SEQUENCE seq_test_table RESTART START WITH 101;
| 維度 | Sequence + Trigger | Identity (ALWAYS) | DEFAULT ON NULL |
|---|---|---|---|
| 版本支援 | 全版本 | 12c+ | 12c+ |
| 性能開銷 | 觸發器上下文切換 | 內核級,最優 | 內核級,最優 |
| 手動指定 ID | 可(觸發器不覆蓋非 NULL) | 不可 | 可 |
| 遷移兼容性 | 最好(標準 SQL) | Oracle 專有 | Oracle 專有 |
| 推薦場景 | 舊版本、需複雜邏輯 | 新項目、嚴格自增 | 新項目、靈活自增 |
ALTER SEQUENCE、RAC 實例故障會丟失緩存值,ID 不連續是正常現象,業務勿依賴連續性。MAXVALUE 設太小:達到上限報 ORA-08004,建議設極大或 CYCLE(極少用)。:OLD.id:BEFORE INSERT 時 :OLD 為 NULL,必須用 :NEW。FORALL + INSERT ... VALUES (:1, :2) 仍會逐行觸發 Trigger,12c+ Identity/DEFAULT 顯著更快。Oracle 實現自增主鍵的標準演進路徑:Sequence + Trigger(通用) → Identity 列(12c+ 原生) → DEFAULT ON NULL(12c+ 最輕量)。新項目優先選擇 GENERATED BY DEFAULT AS IDENTITY 或 DEFAULT ON NULL seq.NEXTVAL,零觸發器、內核級性能、語義清晰。舊版本或需複雜賦值邏輯時,BEFORE INSERT FOR EACH ROW Trigger 依然可靠。記住:序列不連續是特性而非缺陷,業務設計勿依賴連續性。