Oracle Sequence 是獨立於資料表的序號產生器,提供:
CREATE SEQUENCE sequence_name
[INCREMENT BY n] -- 遞增值 (預設 1,負值為遞減)
[START WITH n] -- 起始值 (預設 1)
[{MAXVALUE n | NOMAXVALUE}] -- 最大值 (預設 NOMAXVALUE: 10^27)
[{MINVALUE n | NOMINVALUE}] -- 最小值 (預設 NOMINVALUE: 1)
[{CYCLE | NOCYCLE}] -- 達極值後是否循環 (預設 NOCYCLE)
[{CACHE n | NOCACHE}] -- 記憶體預取數量 (預設 CACHE 20)
[ORDER | NOORDER]; -- RAC 環境下是否保證全域有序 (預設 NOORDER)
-- 標準主鍵序號 (最常用)
CREATE SEQUENCE seq_emp_id
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
CACHE 100; -- 高併發建議較大快取
-- 訂單號:年份前綴 + 序號 (需搭配觸發器或應用層組裝)
CREATE SEQUENCE seq_order_no
START WITH 1
INCREMENT BY 1
MAXVALUE 999999
CYCLE
NOCACHE; -- 業務連號不可跳號時使用 NOCACHE
-- 遞減序號 (特殊需求)
CREATE SEQUENCE seq_reverse
START WITH 10000
INCREMENT BY -1
MINVALUE 1
NOCYCLE;
| 偽欄位 | 行為 | 限制 |
|---|---|---|
| NEXTVAL | 遞增並回傳新值 | 首次呼叫回傳 START WITH 值 |
| CURRVAL | 回傳當前 Session 最後 NEXTVAL 值 | 必須先在該 Session 執行過 NEXTVAL,否則 ORA-08002 |
-- 1. 插入時直接使用
INSERT INTO employees (emp_id, name) VALUES (seq_emp_id.NEXTVAL, 'John');
-- 2. 先取值再多處使用 (同一陳述式多次 NEXTVAL 會產生不同值!)
DECLARE
v_id NUMBER;
BEGIN
v_id := seq_emp_id.NEXTVAL;
INSERT INTO employees (emp_id, name) VALUES (v_id, 'John');
INSERT INTO emp_audit (emp_id, action) VALUES (v_id, 'CREATE');
END;
-- 3. 查詢當前值 (不遞增)
SELECT seq_emp_id.CURRVAL FROM dual;
-- 4. 查詢 Sequence 定義與狀態
SELECT sequence_name, min_value, max_value, increment_by,
cycle_flag, cache_size, last_number
FROM user_sequences
WHERE sequence_name = 'SEQ_EMP_ID';
需 DROP SEQUENCE 後重建。
-- 調整快取大小應對高併發
ALTER SEQUENCE seq_emp_id CACHE 1000;
-- 設定最大值並啟用循環
ALTER SEQUENCE seq_order_no MAXVALUE 999999 CYCLE;
-- 取消快取 (防跳號需求)
ALTER SEQUENCE seq_critical NOCACHE;
DROP SEQUENCE seq_old;
CACHE 指定數量的序號載入 SGA| 策略 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| NOCACHE | 絕不跳號 | 效能極差 (每次磁碟 I/O) | 發票號、支票號等法定連號 |
| CACHE 小值 (10-20) | 平衡效能與間隙 | 仍有跳號 | 一般業務主鍵 |
| CACHE 大值 (1000+) | 極致效能 | 重啟跳號大 | 高併發插入、日誌表 |
| 應用層彌補 | 業務邏輯控制 | 複雜度高 | 嚴格連號需求 |
ORDER 選項:強制跨實例全域有序 (透過實例間協調),嚴重影響效能NOORDER (預設):各實例獨立快取,數值不保證時間序SEQ_<表名>_<用途>,如 SEQ_EMP_IDGRANT SELECT ON seq_emp_id TO app_user; (僅需 SELECT)CREATE PUBLIC SYNONYM seq_emp_id FOR schema.seq_emp_id;LAST_NUMBER 與實際最大 IDid NUMBER GENERATED ALWAYS AS IDENTITY 內建 Sequence,語法更簡潔| 錯誤 | 原因 | 解決 |
|---|---|---|
| ORA-08002: sequence not yet defined | Session 未執行 NEXTVAL 即用 CURRVAL | 先執行 NEXTVAL |
| ORA-08004: sequence exceeds MAXVALUE | 達到最大值且 NOCYCLE | ALTER MAXVALUE 或 CYCLE |
| ORA-04012: sequence not found | 名稱錯誤/權限不足/跨 Schema 無同義詞 | 檢查名稱、GRANT、Synonym |
結語:Sequence 是 Oracle 高效能主鍵生成的基石。理解快取機制、跳號本質、RAC 行為差異,才能在效能與業務連號需求間做出正確架構決策。