Oracle 資料庫並未像 SQL Server 那樣內建 IDENTITY 或 AUTO_INCREMENT 等自增欄位屬性。若要在 Oracle 中實現主鍵自動遞增,主流做法有兩種:觸發器 + 序列 組合,或直接使用 Sequence(序列)。本文將詳細比較這兩種方案的實作細節與效能差異。
此作法在每次 INSERT 前,透過觸發器查詢表中現有的最大 ID 值,再加 1 指派給新行。雖然邏輯直觀,但存在嚴重效能隱憂。
CREATE OR REPLACE TRIGGER trigger_name
BEFORE INSERT ON your_schema.tablename
FOR EACH ROW
DECLARE
v_max_id NUMBER;
CURSOR cur_max IS SELECT MAX(id) FROM your_schema.tablename;
BEGIN
OPEN cur_max;
FETCH cur_max INTO v_max_id;
CLOSE cur_max;
IF v_max_id IS NULL THEN
:new.id := 0; -- 依業務需求設定初始值
ELSE
:new.id := v_max_id + 1; -- 以 1 遞增
END IF;
END;
/
關鍵點說明:
your_schema:資料庫使用者(SID)tablename:目標資料表名稱id:自增欄位名稱每次插入都需執行 SELECT MAX(id),隨著資料量增長,全表掃描成本線性上升。高併發場景下更會引發鎖競爭與「失聯更新」風險,極不推薦用於生產環境。
Oracle 內建 SEQUENCE 物件專為產生唯一、有序數值設計,具備記憶體快取、無鎖高併發等優勢。
CREATE SEQUENCE your_schema.sequence_name
INCREMENT BY 1 -- 每次遞增 1(預設值)
START WITH 1 -- 起始值
NOMAXVALUE -- 不設上限
MINVALUE 1 -- 最小值
CACHE 20 -- 記憶體預先快取 20 個值,減少 I/O
ORDER; -- 確保 RAC 環境下全域有序
-- 插入時直接引用
INSERT INTO your_schema.tablename (id, col1, col2)
VALUES (your_schema.sequence_name.NEXTVAL, 'value1', 'value2');
| 比較維度 | Trigger + MAX(ID) | Sequence |
|---|---|---|
| 效能 | 差(全表掃描、鎖競爭) | 優(記憶體快取、無鎖) |
| 併發支援 | 弱(易發生重複鍵錯誤) | 強(原子性保證) |
| 維護複雜度 | 高(需管理觸發器、游標) | 低(單一物件) |
| 功能豐富度 | 僅支援簡單遞增 | 支援循環、快取、排序等進階選項 |
| 官方建議 | 不推薦 | 標準最佳實踐 |
自 Oracle 12c 起,原生支援 GENERATED AS IDENTITY 語法,底層自動建立序列,語法更簡潔:
CREATE TABLE t (
id NUMBER GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(100)
);
這是現代 Oracle 開發的首選方案,兼具可讀性與效能。
在 Oracle 實現自增主鍵,**Sequence 為唯一正統選擇**。Trigger 方案僅供教學參考,切勿用於實務專案。升級至 12c 以上版本時,請優先採用 Identity Column 簡化開發。