【Oracle】シーケンスを作成する方法完全ガイド|CREATE SEQUENCE全パラメータ・INSERT活用・トリガー自動採番まで解説

【Oracle】シーケンスを作成する方法完全ガイド|CREATE SEQUENCE全パラメータ・INSERT活用・トリガー自動採番まで解説 Oracle

Oracleでテーブルの主キー(ID列)に連番を自動採番するには、シーケンス(SEQUENCE)を使うのが定石です。MySQLの AUTO_INCREMENT に相当しますが、Oracleのシーケンスはテーブルと独立したオブジェクトなので、設定できるパラメータが豊富な分、初めて触れると「どれを指定すべきか」「デフォルトだと何になるのか」が分かりにくいこともあります。

また、CACHECYCLEORDER といったオプションを理解せずに作ると、本番運用でシーケンスが跳んだり、DB再起動後に欠番が大量に発生したりと想定外の問題が起きることがあります。

この記事では CREATE SEQUENCE の全パラメータを実例とともに解説し、INSERT での使い方・トリガーによる自動採番・権限の付与まで、実務で必要な知識をすべてまとめます。

この記事でわかること
・CREATE SEQUENCE の完全な構文と全パラメータの意味
・何も指定しないときのデフォルト値一覧
・CACHE を使うべき理由と DB 再起動時の挙動
・INSERT 文で NEXTVAL を使って連番を挿入する方法
・Oracle 12c 以降の DEFAULT 制約(IDENTITY 列的な使い方)
・トリガーで INSERT 時に自動採番する方法(11g 以前対応)
・CREATE SEQUENCE に必要な権限と権限付与の手順
・RAC 環境で ORDER オプションが必要なケース
スポンサーリンク

CREATE SEQUENCE の基本構文

シーケンスを作成する SQL 文の完全な構文は以下のとおりです。[ ] 内はオプションで、省略するとデフォルト値が使われます。

構文(全パラメータ)
CREATE SEQUENCE シーケンス名
    [ START WITH    開始値        ]  -- 最初に返す値(デフォルト: 1)
    [ INCREMENT BY  増分          ]  -- 1回の NEXTVAL で増える量(デフォルト: 1)
    [ MINVALUE      最小値        ]  -- 最小値(デフォルト: NOMINVALUE = 1)
    [ NOMINVALUE                  ]  -- 最小値なし(デフォルト)
    [ MAXVALUE      最大値        ]  -- 最大値
    [ NOMAXVALUE                  ]  -- 最大値なし(デフォルト)
    [ CYCLE   | NOCYCLE           ]  -- 上限到達後に最初に戻るか(デフォルト: NOCYCLE)
    [ CACHE   n | NOCACHE         ]  -- キャッシュ件数(デフォルト: CACHE 20)
    [ ORDER   | NOORDER           ]  -- 採番順序保証(RAC用、デフォルト: NOORDER)
;

もっともシンプルな書き方は以下です。省略したパラメータはすべてデフォルト値が適用されます。

SQL(最もシンプルな作成例)
CREATE SEQUENCE seq_emp;
シーケンス名の命名規則
・先頭は英字で始める
・使えるのは英字・数字・_(アンダースコア)・$#
・最大30文字(Oracle 12.2以降は128文字)
・引用符なしで作成すると内部的に大文字で格納される
・慣例として SEQ_テーブル名 のように命名するとわかりやすい

全パラメータの詳細と注意点

START WITH:開始値を指定する

シーケンスが最初に返す値です。デフォルトは 1。データ移行などで既存データの最大 ID より大きい値から始めたい場合に指定します。

START WITH は ALTER SEQUENCE で変更できない
ALTER SEQUENCE では INCREMENT BYMAXVALUECACHE などを変更できますが、START WITH だけは変更不可です。採番の開始値を変えたい場合は DROP SEQUENCE で削除して CREATE SEQUENCE で再作成する必要があります。詳細は【Oracle】シーケンスの削除・作成・変更方法を参照してください。
例(1000 から開始する場合)
CREATE SEQUENCE seq_emp
    START WITH 1000;
START WITH と MINVALUE の違い
START WITH は最初の採番値を指定するだけで、その後の動作には関係ありません。MINVALUECYCLE 設定時に上限到達後に戻る値を決めます。たとえば START WITH 1000 MINVALUE 1 とすると、最初は1000から始まり、CYCLE時は1に戻ります。

INCREMENT BY:増分を指定する

1回の NEXTVAL 呼び出しで増える量です。デフォルトは 1負の値を指定するとデクリメント(減算)シーケンスになります。

例(10 ずつ増加する場合)
CREATE SEQUENCE seq_order_no
    INCREMENT BY 10;
例(デクリメントシーケンス:100 から 1 ずつ減らす場合)
CREATE SEQUENCE seq_countdown
    START WITH 100
    INCREMENT BY -1
    MINVALUE 1
    MAXVALUE 100
    NOCYCLE;

MINVALUE / MAXVALUE:最小値・最大値を指定する

デフォルトは NOMINVALUE(= 最小値1)と NOMAXVALUE(= 最大値 9999999999999999999999999999)です。CYCLE と組み合わせる場合は明示的に指定することが重要です。

オプション デフォルト値 説明
NOMINVALUE 1(昇順)/ -10^26(降順) 最小値の制限なし(実質的な最小値)
NOMAXVALUE 10^27(昇順)/ -1(降順) 最大値の制限なし(実質的な最大値)
MINVALUE n 任意の値 CYCLE 時に戻る最小値を明示指定
MAXVALUE n 任意の値 これ以上採番するとエラー or CYCLE で戻る

CYCLE / NOCYCLE:上限到達後の動作を指定する

CYCLE を指定すると、MAXVALUE に達した後に MINVALUE から採番を再開します。NOCYCLE(デフォルト)では MAXVALUE 到達後に ORA-08004 エラーが発生します。

CYCLE 使用時の注意:主キーには使えない
CYCLE を設定すると採番値が重複する可能性があります。テーブルの主キー採番には NOCYCLE(デフォルト)を使い、MAXVALUE に余裕を持たせてください。CYCLE が有効なのは「一時的な番号が必要で重複しても問題ない」用途に限られます。

CACHE / NOCACHE:キャッシュ件数を指定する

CACHE n を指定すると、Oracle がメモリに n 件分の採番値を先読みします。NEXTVAL のたびにディスクへの書き込みが不要になるためパフォーマンスが向上します。デフォルトは CACHE 20

設定 パフォーマンス DB再起動後の欠番 推奨用途
CACHE 20(デフォルト) 高速 最大20件の欠番が発生しうる 一般的な採番(欠番が許容される場合)
CACHE 100 など さらに高速 最大100件の欠番が発生しうる 高頻度インサートのバッチ処理など
NOCACHE 低速 欠番なし 欠番を絶対に許容できない場合のみ
欠番は「仕様」と割り切るのが正解
実務では CACHE によるパフォーマンス向上のメリットが大きいため、CACHE 20 以上を推奨します。「連番に欠番があってはいけない」という要件があっても、NOCACHE より CACHE を使いつつ、欠番を業務ロジックで許容する設計に変更するほうが長期的にはベターです。

ORDER / NOORDER:採番順序の保証(RAC環境)

ORDER を指定すると、Oracle RAC(Real Application Clusters)環境で複数ノード間でも採番の順序が保証されます。通常のシングルインスタンスでは関係なく、デフォルトの NOORDER で問題ありません。

ORDER はパフォーマンスコストがある
RAC 環境で ORDER を有効にすると、採番のたびにノード間で同期処理が走るためパフォーマンスが低下します。「採番値の順序が業務上絶対に必要」な場合に限り使用し、通常は NOORDER(デフォルト)のままで問題ありません。

実践的な作成例

テーブルのID採番用(標準的なパターン)

最も一般的な使い方です。CACHE を指定してパフォーマンスを確保します。

SQL(標準的なID採番シーケンス)
-- 社員テーブル用シーケンス(1から始まる、1ずつ増加、キャッシュ50件)
CREATE SEQUENCE seq_emp
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    NOMAXVALUE
    NOCYCLE
    CACHE 50;

既存データを移行した後にシーケンスを作成する

既にデータが入っているテーブルにシーケンスを後から追加する場合は、現在の最大 ID + 1 から始めます。

SQL(既存データの最大IDを確認してからシーケンスを作成)
-- 1. 現在の最大IDを確認
SELECT MAX(emp_id) FROM emp;
-- 結果が 500 だったとする

-- 2. 501 から始まるシーケンスを作成
CREATE SEQUENCE seq_emp
    START WITH 501
    INCREMENT BY 1
    NOCYCLE
    CACHE 20;

ドキュメント番号など特定フォーマットの採番

「1000 から始まり、10 ずつ増加する」ような採番も指定できます。

SQL(1000から10ずつ増加)
CREATE SEQUENCE seq_doc_no
    START WITH 1000
    INCREMENT BY 10
    MINVALUE 1000
    NOMAXVALUE
    NOCYCLE
    CACHE 20;

INSERT で NEXTVAL を使って連番を挿入する

シーケンスを作成したら シーケンス名.NEXTVAL を INSERT 文で使って連番を挿入します。

SQL(INSERT での NEXTVAL 使用例)
-- 社員テーブルにシーケンスを使って INSERT
INSERT INTO emp (emp_id, emp_name, dept_id)
VALUES (seq_emp.NEXTVAL, '山田太郎', 10);

-- 複数行 INSERT(12c以降 INSERT ALL を使う場合)
INSERT ALL
    INTO emp (emp_id, emp_name) VALUES (seq_emp.NEXTVAL, '山田太郎')
    INTO emp (emp_id, emp_name) VALUES (seq_emp.NEXTVAL, '鈴木花子')
SELECT 1 FROM DUAL;

Oracle 12c 以降:DEFAULT 制約で NEXTVAL を使う

Oracle 12c から、列の DEFAULT 制約に NEXTVAL を指定できるようになりました。これにより INSERT 文でシーケンスを明示的に書かなくても自動採番されます。

SQL(12c以降:DEFAULT ON NULL でシーケンスを自動設定)
-- テーブル作成時にデフォルトを設定
CREATE TABLE emp (
    emp_id   NUMBER DEFAULT seq_emp.NEXTVAL NOT NULL,
    emp_name VARCHAR2(100)
);

-- INSERT 時に emp_id を省略できる
INSERT INTO emp (emp_name) VALUES ('山田太郎');
12c 以降では IDENTITY 列もある
GENERATED AS IDENTITY を使うと、シーケンスを明示的に作らずに自動採番列を定義できます。ただし内部的にはシーケンスが自動生成されます(ISEQ$$_ で始まる名前)。複数テーブルで同じシーケンスを共有したい場合などは、従来の CREATE SEQUENCE を使うほうが柔軟です。

トリガーで INSERT 時に自動採番する(11g 以前対応)

Oracle 11g 以前や、DEFAULT 制約を使えない環境では、BEFORE INSERT トリガーでシーケンスを使う方法が一般的です。

SQL(BEFORE INSERT トリガーで自動採番)
-- シーケンス作成
CREATE SEQUENCE seq_emp
    START WITH 1
    INCREMENT BY 1
    CACHE 20;

-- BEFORE INSERT トリガーで自動採番
CREATE OR REPLACE TRIGGER trg_emp_id
    BEFORE INSERT ON emp
    FOR EACH ROW
BEGIN
    IF :NEW.emp_id IS NULL THEN
        SELECT seq_emp.NEXTVAL INTO :NEW.emp_id FROM DUAL;
    END IF;
END;
/
IF :NEW.emp_id IS NULL THEN という条件を入れることで、INSERT 時に emp_id を明示指定した場合はその値を使い、省略した場合のみシーケンスで採番する設計にしています。これにより既存データのインポートなど、ID を手動指定したい場面でも対応できます。

CREATE SEQUENCE に必要な権限

シーケンスを作成するには CREATE SEQUENCE システム権限が必要です。DBA ロールがあれば既に持っています。

SQL(権限の確認)
-- 自分がどんなシステム権限を持っているか確認
SELECT PRIVILEGE FROM SESSION_PRIVS WHERE PRIVILEGE LIKE '%SEQUENCE%';
SQL(権限の付与:DBA が実行)
-- 特定ユーザーに CREATE SEQUENCE 権限を付与
GRANT CREATE SEQUENCE TO scott;

-- 他スキーマのシーケンスを操作する権限(NEXTVAL/CURRVALの使用)
GRANT SELECT ON hr.seq_emp TO scott;
権限 説明
CREATE SEQUENCE 自スキーマにシーケンスを作成できる
CREATE ANY SEQUENCE 他スキーマを含む任意の場所にシーケンスを作成できる(DBAが使う)
SELECT ON スキーマ.シーケンス名 他スキーマのシーケンスで NEXTVAL/CURRVAL を使用できる
権限の確認方法や付与手順の詳細は【Oracle】ユーザ権限を確認する方法完全ガイドを参照してください。

シーケンスを作成後に確認する

作成したシーケンスは USER_SEQUENCES ビューで確認できます。

SQL(作成したシーケンスを確認)
SELECT
    SEQUENCE_NAME,
    MIN_VALUE,
    MAX_VALUE,
    INCREMENT_BY,
    CYCLE_FLAG,
    CACHE_SIZE,
    LAST_NUMBER
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = 'SEQ_EMP';
シーケンスの確認方法(USER_SEQUENCES・ALL_SEQUENCES・DBA_SEQUENCES の使い分けや NEXTVAL/CURRVAL での現在値確認)は【Oracle】シーケンスの確認方法完全ガイドで詳しく解説しています。

シーケンス作成のよくあるパターン集

パターン1:主キー採番(定番)
CREATE SEQUENCE seq_emp
    START WITH 1
    INCREMENT BY 1
    NOCYCLE
    CACHE 20;
パターン2:データ移行後(既存最大ID+1から開始)
-- MAX(id) が 9999 なら 10000 から開始
CREATE SEQUENCE seq_emp
    START WITH 10000
    INCREMENT BY 1
    NOCYCLE
    CACHE 20;
パターン3:高頻度バッチ用(大きいキャッシュ)
CREATE SEQUENCE seq_log
    START WITH 1
    INCREMENT BY 1
    NOCYCLE
    CACHE 500;
パターン4:欠番不可(トレード番号など)
-- NOCACHE は低速なので業務要件を再検討してから使うこと
CREATE SEQUENCE seq_trade_no
    START WITH 1
    INCREMENT BY 1
    NOCYCLE
    NOCACHE;

作成後にシーケンスを一気に進めたい・リセットしたい場合

テスト後に採番値をリセットしたい、または特定の値まで一気に進めたいという場面があります。START WITH は ALTER で変更できないため、いくつかの対処方法があります。

シーケンスを進める・リセットする方法の詳細
INCREMENT BY を一時的に大きな値に変更して NEXTVAL を1回呼ぶ方法
DROP SEQUENCE + CREATE SEQUENCE で完全リセットする方法
ALTER SEQUENCE … RESTART(Oracle 18c 以降)
これらの手順は【Oracle】シーケンスを進める方法|NEXTVAL・一気に増やす・リセットまで完全解説で詳しく解説しています。

よくある質問

シーケンスを作成できません(ORA-01031: 権限が不足しています)
CREATE SEQUENCE システム権限が付与されていません。DBA 権限を持つユーザーに GRANT CREATE SEQUENCE TO ユーザー名; で権限を付与してもらってください。権限の確認・付与方法は【Oracle】ユーザ権限を確認する方法完全ガイドを参照してください。
START WITH に指定した値より先に NEXTVAL が返ってきます
START WITH は最初の NEXTVAL 値を指定しますが、CACHE が有効な場合は内部的にキャッシュ分を先取りするため、USER_SEQUENCES.LAST_NUMBER がすでに進んだ値になっています。ただし NEXTVAL 自体は START WITH の値から順に返します。
DB を再起動したらシーケンスの値が大きく飛びました
CACHE が有効(デフォルトは CACHE 20)な場合、DB 再起動時にメモリ上のキャッシュが失われ、CACHE 件数分の欠番が発生します。これは Oracle の仕様です。欠番が許容できない場合は NOCACHE に変更しますが、パフォーマンスが低下するため、業務要件を再検討してから設定してください。
シーケンスが作成できる件数に上限はありますか?
特定の件数制限はありません。ただしオブジェクト数はシステムリソースに依存します。シーケンス名はスキーマ内でユニークである必要があります。
シーケンスの設定を後から変更できますか?
はい、ALTER SEQUENCE で変更できます。ただし START WITH は変更できません。開始値を変えたい場合は DROP して再作成する必要があります。変更手順の詳細は【Oracle】シーケンスの変更方法を参照してください。
複数のテーブルで同じシーケンスを共有できますか?
はい、シーケンスはテーブルとは独立したオブジェクトなので、1つのシーケンスを複数テーブルの INSERT で使えます。ただし、各テーブルのキー採番を共有すると「テーブルAに1、テーブルBに2、テーブルAに3…」と各テーブル単独では飛び番になるため、設計時に意図を明確にしておくことが重要です。
CYCLE を設定しているのに ORA-08004 が出ます
CYCLE を設定している場合でも、MINVALUEMAXVALUE の設定が不適切だとエラーになることがあります。昇順シーケンスの場合は MAXVALUE > MINVALUE、かつ CYCLE 後に少なくとも1つ以上の値が採番できる範囲を確保してください。

まとめ

Oracle でシーケンスを作成する際のポイントをまとめます。

パラメータ デフォルト 実務でのポイント
START WITH 1 データ移行後は既存最大ID+1を指定する
INCREMENT BY 1 通常は1。負値でデクリメントシーケンスも作れる
MINVALUE / MAXVALUE 制限なし CYCLE 使用時は明示指定を推奨
CYCLE / NOCYCLE NOCYCLE 主キー採番には必ず NOCYCLE を使う
CACHE n CACHE 20 性能重視なら増やす(100〜500)。欠番不可の場合のみ NOCACHE
ORDER / NOORDER NOORDER RAC 環境で順序が必須な場合のみ ORDER を指定

作成後は USER_SEQUENCES で設定を確認し、INSERT 文で NEXTVAL を使って採番します。Oracle 12c 以降なら DEFAULT 制約にシーケンスを設定でき、11g 以前では BEFORE INSERT トリガーが自動採番の定番パターンです。

シーケンスに関連する操作については以下の記事も参照してください。