Oracle SQL シーケンス作成と自動採番の基礎【CREATE SEQUENCE】

Oracle Master Silver

Oracle シーケンス (SEQUENCE) は、一意な連番(数値)を自動生成するためのデータベース・オブジェクトです。主にテーブルの主キー(Primary Key)用に、重複しないIDを効率的に採番するために利用されます。

この記事では、CREATE SEQUENCE 文によるシーケンスの作成方法から、NEXTVAL を使用した自動採番の実装、そして運用上の注意点である「欠番」や「リセット方法」について、Oracle Database 19c を前提に初心者向けに解説します。

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


この記事でわかること

  • Oracle シーケンス の基本的な仕組みと作成手順
  • NEXTVAL / CURRVAL を使った SQL での自動採番
  • 欠番が発生する理由と、連番をリセットする正しい手法

結論:シーケンス利用の最短ステップ

自動採番を実装するための「やることリスト」は以下の通りです。

  1. 作成: CREATE SEQUENCE で順序オブジェクトを作成する。
  2. 確認: USER_SEQUENCES ビューで設定を確認する。
  3. 使用: INSERT 文などで シーケンス名.NEXTVAL を呼び出す。

シーケンス(SEQUENCE)とは?

シーケンスは、「最後に渡した番号は X なので、次は X+1 を渡す」 という管理をメモリ上で行うカウンターのような仕組みです。

主なメリット

  • 自動採番: アプリケーション側で「現在の最大ID」を調べて+1する処理が不要になります。
  • 高速・高並列: 複数のトランザクションが同時にアクセスしても、ロック競合を最小限に抑えて番号を発行できます(Oracle Database のメモリ構造である SGA 内で管理されるため)。
  • 独立性: 特定のテーブルに依存しないため、複数のテーブルで1つのシーケンスを共有することも可能です。

Note: Oracle Database 12c 以降では、テーブル列定義で GENERATED AS IDENTITY を指定する「ID列(Identity Column)」も利用可能です。これは内部的にシーケンスを使用していますが、より簡潔に定義できます。本記事では、基本となるシーケンスオブジェクト自体について解説します。


手順1:シーケンスの作成 (CREATE SEQUENCE)

基本構文と主要なオプションを解説します。

基本構文

CREATE SEQUENCE シーケンス名
  [START WITH n]
  [INCREMENT BY n]
  [MAXVALUE n | NOMAXVALUE]
  [MINVALUE n | NOMINVALUE]
  [CYCLE | NOCYCLE]
  [CACHE n | NOCACHE];

パラメータの解説

パラメータ説明推奨設定・備考
START WITH採番を開始する初期値。デフォルトは 1。既存データがある場合は MAX(ID) + 1 を指定。
INCREMENT BY増分値。1 なら 1, 2, 3… と増える。負の値を指定すると減少シーケンスになる。
CACHEメモリ上に事前に割り当てる番号の数。重要: デフォルトは 20。パフォーマンス向上のため、高負荷環境では 100 以上を検討。ただしインスタンス障害時にキャッシュ分が欠番となる(後述)。
CYCLE最大値に達した後、初期値に戻るか。通常の主キー用途では NOCYCLE (デフォルト) 推奨。

手順2:実機での作成と使用例

実際に SQL*Plus や SQL Developer で実行可能な例を示します。ここでは、従業員マスタ (EMPLOYEES) の ID を自動採番します。

前提条件

  • 接続ユーザー: 一般ユーザー(例: SCOTT)またはDBA
  • 必要な権限: CREATE SEQUENCE, CREATE TABLE

1. シーケンスとテーブルの作成

まずはシーケンスを作成します。ここでは 1 から始まり 1 ずつ増える設定にします。

-- シーケンスの作成
CREATE SEQUENCE seq_emp_id
  START WITH 1
  INCREMENT BY 1
  NOCYCLE
  NOCACHE;

-- テーブルの作成
CREATE TABLE employees (
    id   NUMBER PRIMARY KEY,
    name VARCHAR2(50)
);

解説: NOCACHE を指定すると、番号を取得するたびにデータディクショナリを更新するため信頼性は高いですが、大量のINSERTを行うシステムではパフォーマンスに影響が出る場合があります(通常はデフォルトのCACHE 20で問題ありません)。

2. NEXTVAL によるデータの挿入

INSERT 文の VALUES 句で シーケンス名.NEXTVAL を指定します。

-- 1件目の挿入(自動的に 1 が割り当てられる)
INSERT INTO employees (id, name)
VALUES (seq_emp_id.NEXTVAL, 'John Doe');

-- 2件目の挿入(自動的に 2 が割り当てられる)
INSERT INTO employees (id, name)
VALUES (seq_emp_id.NEXTVAL, 'Jane Smith');

-- コミットして確定
COMMIT;

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

3. 結果の確認

テーブルのデータと、シーケンスの現在値を確認します。

-- データの確認
SELECT * FROM employees;

-- シーケンスの現在確認(CURRVALは自セッションでNEXTVAL実行後のみ参照可)
SELECT seq_emp_id.CURRVAL FROM dual;

実行結果イメージ:

SQL> CREATE SEQUENCE seq_emp_id
2 START WITH 1
3 INCREMENT BY 1
4 NOCYCLE
5 NOCACHE;

Sequence created.

SQL> CREATE TABLE employees (
2 id NUMBER PRIMARY KEY,
3 name VARCHAR2(50)
4 );

Table created.

SQL> INSERT INTO employees (id, name)
2 VALUES (seq_emp_id.NEXTVAL, 'John Doe');

1 row created.

SQL> INSERT INTO employees (id, name)
2 VALUES (seq_emp_id.NEXTVAL, 'Jane Smith');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM employees;

ID NAME
---------- --------------------------------------------------
★ 1 John Doe
★ 2 Jane Smith

SQL> SELECT seq_emp_id.CURRVAL FROM dual;

CURRVAL
----------
2

運用・トラブルシューティング

シーケンス運用時によくある疑問やトラブル、その対処法です。

よくあるエラーと対処

ORAエラー原因対処・確認
ORA-08002: 順序…はまだこのセッションで定義されていませんそのセッションで NEXTVAL を一度も実行せずに CURRVAL を参照した。まず NEXTVAL を実行するか、確認目的であれば USER_SEQUENCES ビューの LAST_NUMBER を参照する。
ORA-02289: 順序が存在しませんシーケンス名が間違っているか、権限がない。スペル確認、または GRANT SELECT ON シーケンス名 TO ユーザー の権限確認。

欠番(ギャップ)について

シーケンスは「完全な連番」を保証するものではありません。以下のケースで欠番が発生します。仕様として理解しておく必要があります。

  1. ロールバック: NEXTVAL で取得した番号を使って INSERT した後、トランザクションをロールバックしても、シーケンスのカウンターは戻りません。
  2. キャッシュの消失: CACHE 設定あり(デフォルト20)の場合、DB再起動やクラッシュ時にメモリ上の未使用番号が破棄され、再起動後はその分が飛んで採番されます。

シーケンスのリセット(初期化)方法

テスト完了後などで、シーケンス番号を 1 に戻したい場合があります。

方法A:DROP して作り直す(推奨・確実)

最もシンプルですが、シーケンスに対する権限(GRANT)も消えるため、再付与が必要です。

-- 削除
DROP SEQUENCE seq_emp_id;

-- 再作成(権限付与も忘れずに)
CREATE SEQUENCE seq_emp_id START WITH 1 ...;

方法B:INCREMENT BY を変更して戻す(上級・運用中向け)

オブジェクトIDや権限を維持したい場合のテクニックです。

  1. 現在の値を確認。
  2. ALTER SEQUENCE で増分をマイナスに設定。
  3. NEXTVAL で値を下げる。
  4. 増分を 1 に戻す。
-- 例:現在値が 1000 で 1 に戻したい場合
ALTER SEQUENCE seq_emp_id INCREMENT BY -999 MINVALUE 0;
SELECT seq_emp_id.NEXTVAL FROM dual; -- これで 1 になる
ALTER SEQUENCE seq_emp_id INCREMENT BY 1;

FAQ:よくある質問

Q1. CACHE(キャッシュ)とは何ですか?メリットは?

シーケンスの値をあらかじめメモリ上にまとめて確保しておく機能です。デフォルトは 20 です。ディスクへの書き込み回数を減らせるため、同時に大量のアクセスがあるシステムではパフォーマンスが向上します。ただし、DB再起動時に確保分が欠番になります。

Q2. 欠番を絶対に防ぐ方法はありますか?

シーケンス機能だけで完全に防ぐ方法はありません。NOCACHE オプションでキャッシュによる欠番は減らせますが、ロールバックによる欠番は防げません。税務書類の番号など、完全な連番が法的に必須な場合は、シーケンスを使わず、別の採番テーブルを用意して排他制御(ロック)しながら管理する必要があります(ただし性能は低下します)。

Q3. 本番環境のシーケンス設定を確認するには?

USER_SEQUENCES ビュー(自分の所有)、または ALL_SEQUENCES ビュー(アクセス権があるもの)を参照してください。

SELECT sequence_name, min_value, max_value, increment_by, cache_size, last_number
FROM user_sequences
WHERE sequence_name = 'SEQ_EMP_ID';

last_number は、キャッシュ利用時は「メモリに確保した次の番号」を示すため、現在発行されている番号より大きい値が表示されることがあります。


まとめ

  • 自動採番: CREATE SEQUENCENEXTVAL で簡単に一意なIDを生成できる。
  • 構成: START WITH で開始値、INCREMENT BY で増分を指定する。
  • 注意点: ロールバックやキャッシュの仕組み上、欠番は必ず発生する前提で設計する。
  • リセット: 基本は再作成 (DROP & CREATE) だが、権限消失に注意。

シーケンスはデータベース設計の基本パーツです。特性を理解して、効率的なデータ管理に役立ててください。


注記: 本記事は Oracle Database 19c を対象に解説しています。バージョンによって既定値や挙動が異なる場合があります。


[参考]
Oracle Databaseデータベース管理者ガイド 19c

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

タイトルとURLをコピーしました