Sequence (序列) 是獨立的資料庫物件,產生單調遞增 (或遞減) 的數值,常用於主鍵、單據編號、審計追蹤 ID。與 Identity Column (12c+) 不同,Sequence 可跨表共用、可手動控制、支援緩存 (CACHE) 提升效能。
CREATE SEQUENCE [schema.]sequence_name
[INCREMENT BY n] -- 間距,正數遞增,負數遞減 (預設 1)
[START WITH n] -- 起始值 (預設 1 或 INCREMENT 符號決定的極值)
[MAXVALUE n | NOMAXVALUE] -- 最大值 (預設 NOMAXVALUE = 10^27)
[MINVALUE n | NOMINVALUE] -- 最小值 (預設 NOMINVALUE = 1 或 -10^26)
[CYCLE | NOCYCLE] -- 達極值後是否循環 (預設 NOCYCLE)
[CACHE n | NOCACHE] -- 記憶體預取數量 (預設 20,NOCACHE 表不緩存)
[ORDER | NOORDER]; -- RAC 環境是否保證全序 (預設 NOORDER,效能較好)
-- 標準主鍵序列 (高併發、允許跳號)
CREATE SEQUENCE seq_order_id
START WITH 1 INCREMENT BY 1
NOMAXVALUE NOCYCLE
CACHE 1000 NOORDER;
-- 發票號序列 (不允許跳號、需連續)
CREATE SEQUENCE seq_invoice_no
START WITH 10000 INCREMENT BY 1
MAXVALUE 99999999 NOCYCLE
NOCACHE ORDER; -- 單實例 ORDER 無額外成本,RAC 下有協調開銷
-- 遞減序列 (特殊業務)
CREATE SEQUENCE seq_reverse
START WITH 1000 INCREMENT BY -1
MINVALUE 1 MAXVALUE 1000
CYCLE NOCACHE;
sequence_name.NEXTVAL:取得下一個值,**每次呼叫遞增一次** (即使同一 SQL 多次引用也各自遞增)。sequence_name.CURRVAL:取得**當前 Session 最後一次 NEXTVAL 的值**,必須在該 Session 已呼叫過 NEXTVAL 後才能使用,否則報 ORA-08002。DEFAULT seq.NEXTVAL)CREATE OR REPLACE TRIGGER trg_orders_bir
BEFORE INSERT ON orders
FOR EACH ROW
WHEN (NEW.order_id IS NULL) -- 僅在未提供值時自動填充
BEGIN
SELECT seq_order_id.NEXTVAL INTO :NEW.order_id FROM dual;
END;
/
-- 測試
INSERT INTO orders (cust_id, amt) VALUES (1001, 123.45); -- order_id 自動產生
INSERT INTO orders (order_id, cust_id, amt) VALUES (9999, 1002, 500); -- 手動指定,觸發器不覆蓋
CREATE TABLE orders (
order_id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 CACHE 1000),
cust_id NUMBER,
amt NUMBER(10,2)
);
-- 或 GENERATED BY DEFAULT ON NULL (允許手動指定,NULL 時自動產生)
-- Identity 內建序列,無需獨立物件、觸發器,效能略優、遷移性較好 (標準 SQL)。
LAST_NUMBER,分配 CACHE 個值到 SGA (Sequence Cache)。NEXTVAL 直接從記憶體取值,極快,無 I/O。LAST_NUMBER += CACHE,重新填滿 Cache。LAST_NUMBER 繼續,**發生跳號** (跳過的數量 ≤ CACHE)。| 場景 | 建議 CACHE | 理由 |
|---|---|---|
| 高併發 OLTP 主鍵 | 1000~10000 | 減少字典更新頻率、Library Cache 鎖爭用,跳號可接受 | 發票/憑證號 (法規要求連續) | NOCACHE | 犧牲效能換取絕對連續,單實例 ORDER 同效 |
| 低頻序列 (日誌編號、批次號) | 20 (預設) 或 NOCACHE | 無併發壓力,簡單即可 |
| RAC 環境高併發 | 1000+ + NOORDER | 避免全序協調開銷,接受輕微亂序 |
ALTER SEQUENCE seq_order_id
INCREMENT BY 10
MAXVALUE 1000000
CYCLE
NOCACHE;
-- 注意:START WITH 無法修改,需 DROP 再 CREATE
DROP SEQUENCE seq_order_id;
SELECT sequence_name, min_value, max_value, increment_by,
cycle_flag, order_flag, cache_size, last_number
FROM user_sequences
WHERE sequence_name = 'SEQ_ORDER_ID';
| 問題 | 原因 | 解決 |
|---|---|---|
| ORA-08002: sequence CURRVAL not yet defined in this session | 未先呼叫 NEXTVAL 即用 CURRVAL | 確保邏輯先取 NEXTVAL,或改用 PL/SQL 區塊封裝 |
| ORA-08004: sequence NEXTVAL exceeds MAXVALUE | 達到 MAXVALUE 且 NOCYCLE | 監控 LAST_NUMBER,預警擴大 MAXVALUE 或 CYCLE |
| 同一 INSERT 多次引用 NEXTVAL 值不同 | 每次引用皆遞增 | 用 PL/SQL 變數暫存:v_id := seq.NEXTVAL; INSERT ... VALUES (v_id, v_id); |
| RAC 下序列值亂序 | NOORDER (預設) 各實例獨立 Cache | 業務需全序改 ORDER (效能代價),或應用層接受亂序 |
| 序列值跳號大量 | CACHE 過大 + 頻繁異常重啟 | 縮小 CACHE、改善穩定性、接受跳號業務邏輯 |
-- 僅供參考,需評估應用相容性
CREATE SEQUENCE seq_scalable
SCALE EXTEND -- 自動在序列值前加入 6 位元組實例/會話偏移,極大降低爭用
START WITH 1 INCREMENT BY 1
CACHE 1000 NOORDER;
Sequence 是 Oracle 產生唯一編號的核心工具。掌握 CACHE/NOORDER 對效能的決定性影響、NEXTVAL/CURRVAL 的 Session 語意、跳號風險與業務容忍度的權衡、12c+ Identity Column 的替代優勢,即能在高併發、高可用、跨平台遷移等場景下做出最佳選擇。