【Oracle】シーケンスを進める方法|NEXTVAL・一気に増やす・リセットまで完全解説

Oracleのシーケンスは主キーや採番に使われますが、「テストで大量に消費してしまった」「現在値を確認したい」「一気に特定の値まで進めたい」といった場面は実務でよく発生します。

この記事では、シーケンスの基本(NEXTVAL/CURRVAL)から、大量に進める3つの方法、現在値の確認、ALTER SEQUENCEでの設定変更、リセット方法まで体系的に解説します。

この記事で学べること

  • NEXTVAL・CURRVALの使い方と違い
  • シーケンスを1件ずつ進める基本操作
  • シーケンスを一気に大量に進める3つの方法(INCREMENT BY・PL/SQL・CONNECT BY)
  • USER_SEQUENCES / ALL_SEQUENCESで現在値を確認する方法
  • ALTER SEQUENCEでインクリメント値・最大値・キャッシュを変更する方法
  • シーケンスをリセット(特定の値に戻す)する方法
  • INSERT時の自動採番・シーケンスのギャップに関する注意点
スポンサーリンク

Oracleシーケンスとは

シーケンス(SEQUENCE)は、一意な整数値を順番に生成するデータベースオブジェクトです。主に主キーの自動採番や、複数セッション間で重複しない番号を払い出す目的で使われます。

主なオプション 意味 デフォルト値
START WITH 開始値 1
INCREMENT BY 増分値(負の値で降順も可) 1
MAXVALUE 最大値 10^27(実質無制限)
MINVALUE 最小値 1
CYCLE 最大値に達したら最小値から再開 NOCYCLE
CACHE メモリにキャッシュする値の個数(高速化) 20

シーケンスの作成例

SQL – CREATE SEQUENCE
CREATE SEQUENCE my_sequence  START WITH    1  INCREMENT BY  1  MAXVALUE      9999999999  NOCYCLE  CACHE         20;

NEXTVAL・CURRVALの使い方

シーケンスの操作は NEXTVALCURRVAL の2つの疑似列で行います。

疑似列 動作 注意点
シーケンス名.NEXTVAL シーケンスを1つ進めて次の値を返す 呼び出すたびに必ず増加する(ロールバックしても戻らない)
シーケンス名.CURRVAL 現在のセッションで最後に取得した値を返す 同一セッション内でNEXTVALを1回以上呼んでいないとエラー

基本的な使い方

SQL – NEXTVAL・CURRVAL
-- 次の値を取得(シーケンスが1進む)SELECT my_sequence.NEXTVAL FROM dual;-- 現在のセッションで最後に取得した値を確認SELECT my_sequence.CURRVAL FROM dual;-- INSERT時に自動採番INSERT INTO orders (order_id, product_name, quantity)VALUES (my_sequence.NEXTVAL, 'ノートPC', 2);

注意:NEXTVALは呼び出した時点でシーケンスが進みます。トランザクションをロールバックしてもシーケンス値は元に戻りません。INSERTが失敗してロールバックした場合、その番号は欠番になります。

シーケンスを1件ずつ進める

通常の用途では NEXTVAL を1回呼ぶだけです。

SQL – 1件ずつ進める
SELECT my_sequence.NEXTVAL FROM dual;-- → 1SELECT my_sequence.NEXTVAL FROM dual;-- → 2SELECT my_sequence.NEXTVAL FROM dual;-- → 3

シーケンスを一気に大量に進める3つの方法

数十件程度ならNEXTVALの繰り返しで済みますが、数百・数千件単位で進めたい場合は以下の方法が効率的です。

方法1:INCREMENT BY を一時変更する(最もシンプル)

シーケンスのインクリメント値を一時的に変更し、NEXTVALを1回呼んで一気に進める方法です。シンプルで確実なため、実務でよく使われます。

SQL – 100進める例
-- ① インクリメント値を100に変更ALTER SEQUENCE my_sequence INCREMENT BY 100;-- ② NEXTVALを1回呼ぶ(100進む)SELECT my_sequence.NEXTVAL FROM dual;-- ③ インクリメント値を1に戻すALTER SEQUENCE my_sequence INCREMENT BY 1;

ポイント:ALTER SEQUENCEには ALTER権限(または自スキーマのシーケンスであること)が必要です。③のインクリメント値を元に戻すのを忘れないよう、必ずセットで実行してください。

方法2:PL/SQLでループして進める

PL/SQLのFORループでNEXTVALを指定回数呼び出す方法です。連続した番号を正確に消費したい場合に使います。ただし件数が多いと処理時間がかかるため、数百件程度に向いています。

SQL – PL/SQLで100回NEXTVAL
DECLARE  v_dummy NUMBER;BEGIN  FOR i IN 1..100 LOOP    SELECT my_sequence.NEXTVAL    INTO   v_dummy    FROM   dual;  END LOOP;END;/

方法3:CONNECT BY LEVEL を使う(クエリ1発)

階層問合せの CONNECT BY LEVEL を使って1つのSELECT文で複数回NEXTVALを呼び出す方法です。SQLのみで完結するため手軽です。

SQL – CONNECT BY LEVELで1000進める
SELECT my_sequence.NEXTVALFROM  dualCONNECT BY LEVEL <= 1000;-- 1000行返るので /dev/null 相当の処理で捨てる-- 大量件数でも方法1(INCREMENT BY)の方が速い

3つの方法の比較

方法 手軽さ 大量件数 必要な権限
INCREMENT BY変更 ★★★ ◎(一瞬) ALTER SEQUENCE権限が必要
PL/SQLループ ★★ △(件数が多いと遅い) SELECT権限のみ
CONNECT BY LEVEL ★★★ △(大量行を返す) SELECT権限のみ

シーケンスの現在値・設定を確認する

シーケンスの現在値(LAST_NUMBER)や設定は USER_SEQUENCES(自スキーマ)または ALL_SEQUENCES(アクセス可能なもの全て)で確認できます。

SQL – シーケンスの現在値確認
-- 自スキーマのシーケンス一覧SELECT  sequence_name,  min_value,  max_value,  increment_by,  last_number,   -- 次にNEXTVALで返る予定の値(キャッシュがある場合は先読み済みの値)  cache_size,  cycle_flag,  order_flagFROM user_sequencesWHERE sequence_name = 'MY_SEQUENCE';  -- 大文字で指定

注意:LAST_NUMBER はキャッシュサイズ分先読みした値を示します。たとえば現在値が10でCACHE=20の場合、LAST_NUMBERは30になることがあります。正確な「次に払い出される値」を知るには、一度NEXTVALを呼んでCURRVALで確認するのが確実です。

ALTER SEQUENCEでシーケンスの設定を変更する

既存のシーケンスのプロパティは ALTER SEQUENCE で変更できます。ただし START WITH は変更不可(DROPして再作成が必要)です。

SQL – ALTER SEQUENCEの各種変更
-- インクリメント値を変更ALTER SEQUENCE my_sequence INCREMENT BY 10;-- 最大値を変更ALTER SEQUENCE my_sequence MAXVALUE 99999;-- キャッシュサイズを変更(高頻度採番の高速化に有効)ALTER SEQUENCE my_sequence CACHE 100;-- キャッシュを無効化(RAC環境で採番の抜けを防ぐ場合など)ALTER SEQUENCE my_sequence NOCACHE;-- 循環設定を有効にするALTER SEQUENCE my_sequence CYCLE;

シーケンスを特定の値にリセットする

OracleのシーケンスにはMySQLの AUTO_INCREMENT = n のような直接リセット構文がありません。以下の方法でリセットします。

方法1:DROP & CREATE(最も確実)

シーケンスを削除して同じ名前で再作成します。シーケンスを参照しているビュー・シノニムがない場合はこれが最も簡単です。

SQL – DROP & CREATE でリセット
DROP SEQUENCE my_sequence;CREATE SEQUENCE my_sequence  START WITH   1  INCREMENT BY 1  NOCYCLE  CACHE        20;

方法2:INCREMENT BY に負の値を設定して値を下げる

現在値から目標値まで「負のインクリメント」で引き戻す方法です。DROP不要でシーケンスを維持したまま値を下げられます。

SQL – 現在値1000を1に戻す例
-- 現在値を確認(例: LAST_NUMBER = 1000)SELECT last_number FROM user_sequencesWHERE  sequence_name = 'MY_SEQUENCE';-- ① MINVALUEを1に設定(下限を下げる)ALTER SEQUENCE my_sequence MINVALUE 1;-- ② INCREMENT BY を -(現在値 - 目標値 + 1) に設定-- 例: 現在値1000から1に戻す場合 → -(1000 - 1) = -999ALTER SEQUENCE my_sequence INCREMENT BY -999;-- ③ NEXTVALを1回呼ぶ(1に進む)SELECT my_sequence.NEXTVAL FROM dual;-- → 1-- ④ INCREMENT BY を1に戻すALTER SEQUENCE my_sequence INCREMENT BY 1;

Oracle 18c以降:Oracle 18cからは ALTER SEQUENCE my_sequence RESTART START WITH 1; という構文でシンプルにリセットできます。本番環境のバージョンを確認して使い分けてください。

よくある質問(FAQ)

ロールバックするとシーケンスも元の値に戻りますか?

戻りません。シーケンスはトランザクション外で管理されるため、INSERTをROLLBACKしてもNEXTVALで進んだ値は元に戻りません。これは設計上の仕様であり、複数セッション間での重複を防ぐために必要な動作です。そのため、シーケンスを主キーとして使うテーブルでは採番に欠番が発生することを前提に設計してください。

シーケンスの現在値(NEXTVAL前の値)を取得するには?

CURRVALは「同一セッションで最後に取得したNEXTVAL」を返すため、NEXTVALを呼ばずに現在値を確認するには USER_SEQUENCES.LAST_NUMBER を使います。ただしキャッシュがある場合は先読み分が加算されるため、正確な値ではないことに注意してください。

SELECT last_number FROM user_sequences WHERE sequence_name = 'MY_SEQUENCE';
他スキーマのシーケンスをNEXTVALで使いたい

スキーマ名を指定他スキーマ名.シーケンス名.NEXTVAL)するか、シノニムを作成します。権限は GRANT SELECT ON スキーマ.シーケンス TO ユーザー; で付与してください。

まとめ

Oracleシーケンス操作のポイントを整理します。

やりたいこと 使う方法
1件ずつ進める SELECT シーケンス名.NEXTVAL FROM dual
大量に一気に進める(推奨) ALTER SEQUENCE ... INCREMENT BY N → NEXTVAL → 元に戻す
現在値を確認する SELECT last_number FROM user_sequences WHERE ...
1にリセットする(シンプル) DROP SEQUENCECREATE SEQUENCE START WITH 1
1にリセットする(DROP不要) ALTER SEQUENCE INCREMENT BY -(現在値-1) → NEXTVAL → 元に戻す

シーケンスはロールバックしても値が戻らない点と、CACHE設定によるLAST_NUMBERのズレに注意しながら運用しましょう。大量に進める必要がある場合は、INCREMENT BY変更が最もシンプルで高速です。