【Oracle】シーケンスの削除・作成・変更方法(DROP / CREATE / ALTER SEQUENCE)

Oracleデータベースで連番を自動生成するシーケンス(SEQUENCE)は、主キーの採番やユニークIDの生成に欠かせないオブジェクトです。

しかし、テーブル設計の見直しやシステム移行の際に「シーケンスを削除したい」「番号をリセットしたい」と思ったことはありませんか?

この記事では、DROP SEQUENCEによるシーケンスの削除方法を中心に、シーケンスの作成・確認・変更・リセットNEXTVAL/CURRVALの使い方他RDBMS(PostgreSQL・SQL Server・MySQL)との比較よくあるエラー(ORA-02289等)と対処法まで、実務で使える知識を網羅的に解説します。

スポンサーリンク

シーケンス(SEQUENCE)とは

シーケンスとは、Oracleが提供する一意の連番を自動生成するデータベースオブジェクトです。テーブルとは独立して存在し、複数のテーブルやセッションから共有して利用できます。

シーケンスの特徴

  • テーブルとは独立したデータベースオブジェクト
  • 複数のテーブル・セッションから同時アクセス可能
  • 採番はギャップ(欠番)が発生する場合がある(ロールバック時など)
  • 主キーやユニークIDの生成に最適
  • MySQLの AUTO_INCREMENT とは異なり、テーブルに紐付かない

AUTO_INCREMENTとの違い

MySQLの AUTO_INCREMENT はテーブルのカラムに直接設定しますが、Oracleのシーケンスはテーブルから独立しています。

比較項目 Oracle SEQUENCE MySQL AUTO_INCREMENT
オブジェクト種別 独立したDBオブジェクト カラム属性
テーブルとの関係 1つのシーケンスを複数テーブルで共有可能 1テーブル1カラムのみ
採番タイミング NEXTVAL呼び出し時 INSERT時に自動
欠番の可能性 あり(ロールバック・キャッシュ等) あり(ロールバック時)
減少方向の採番 可能(DECREMENT BY) 不可
循環(サイクル) 可能(CYCLE) 不可

シーケンスの削除方法(DROP SEQUENCE)

シーケンスを削除するには、DROP SEQUENCE 文を使用します。

基本構文

構文
DROP SEQUENCE [スキーマ名.]シーケンス名;

ポイント:DROP SEQUENCE はDDL文のため、実行と同時に暗黙的にCOMMITされます。ROLLBACK で取り消すことはできません。

実行例

SQL
-- シーケンスを削除
DROP SEQUENCE emp_seq;

-- スキーマを指定して削除
DROP SEQUENCE hr.emp_seq;

実行結果

Sequence dropped.

削除前の確認

シーケンスを削除する前に、そのシーケンスが他のオブジェクト(トリガー、プロシージャ等)で参照されていないか確認しましょう。

SQL
-- シーケンスを参照しているオブジェクトを確認
SELECT name, type, referenced_name
FROM user_dependencies
WHERE referenced_name = 'EMP_SEQ'
  AND referenced_type = 'SEQUENCE';

注意:シーケンスを削除しても、そのシーケンスを参照しているトリガーやプロシージャは自動削除されません。参照元オブジェクトは INVALID(無効)状態になり、次回実行時にエラーが発生します。

存在しないシーケンスの削除

存在しないシーケンスを削除しようとすると ORA-02289 エラーが発生します。スクリプトで安全に削除したい場合は、PL/SQLで例外処理を行います。

PL/SQL
-- 存在する場合のみ削除(エラーを無視)
BEGIN
  EXECUTE IMMEDIATE 'DROP SEQUENCE emp_seq';
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -2289 THEN
      RAISE;
    END IF;
END;
/

Oracle 23c以降の新構文

  • Oracle 23cから DROP SEQUENCE IF EXISTS 構文が使えます
  • 例: DROP SEQUENCE IF EXISTS emp_seq;
  • 23c未満ではPL/SQLの例外処理で代替してください

シーケンスの確認方法

現在のスキーマに存在するシーケンスの一覧や設定を確認する方法です。

USER_SEQUENCES:自分のシーケンスを確認

SQL
-- 自分が所有するシーケンスの一覧と設定を確認
SELECT sequence_name,
       min_value,
       max_value,
       increment_by,
       last_number,
       cache_size,
       cycle_flag,
       order_flag
FROM user_sequences
ORDER BY sequence_name;

実行結果

SEQUENCE_NAME  MIN_VALUE  MAX_VALUE             INCREMENT_BY  LAST_NUMBER  CACHE_SIZE  CYCLE_FLAG  ORDER_FLAG
-------------  ---------  --------------------  ------------  -----------  ----------  ----------  ----------
DEPT_SEQ               1  9999999999999999999              1          100          20  N           N
EMP_SEQ                1  9999999999999999999              1         1050          20  N           N
ORDER_SEQ              1  9999999999999999999             10            1          20  N           N
カラム名 説明
SEQUENCE_NAME シーケンス名
MIN_VALUE 最小値
MAX_VALUE 最大値
INCREMENT_BY 増分値
LAST_NUMBER 次にキャッシュされる値(現在値ではない)
CACHE_SIZE キャッシュするシーケンス値の数
CYCLE_FLAG 最大値到達時に循環するか(Y/N)
ORDER_FLAG 順序保証するか(Y/N、RAC環境用)

注意:LAST_NUMBER は「次に払い出される値」ではなく、「次にキャッシュされる先頭の値」です。現在の採番値を正確に知りたい場合は シーケンス名.CURRVAL を使用してください。

ALL_SEQUENCES:アクセス可能なすべてのシーケンス

SQL
-- 他スキーマのシーケンスも含めて確認
SELECT sequence_owner,
       sequence_name,
       increment_by,
       last_number
FROM all_sequences
WHERE sequence_owner = 'HR'
ORDER BY sequence_name;

特定のシーケンスが存在するか確認

SQL
-- 特定のシーケンスが存在するか確認
SELECT COUNT(*) AS seq_exists
FROM user_sequences
WHERE sequence_name = 'EMP_SEQ';

シーケンスの作成(CREATE SEQUENCE)

新しいシーケンスを作成する構文とオプションを解説します。

基本構文

構文
CREATE SEQUENCE [スキーマ名.]シーケンス名
  [START WITH     初期値]
  [INCREMENT BY   増分値]
  [MINVALUE       最小値 | NOMINVALUE]
  [MAXVALUE       最大値 | NOMAXVALUE]
  [CACHE          キャッシュ数 | NOCACHE]
  [CYCLE        | NOCYCLE]
  [ORDER        | NOORDER];

オプションの詳細

オプション 説明 デフォルト
START WITH シーケンスの開始値 1(昇順)/ MAXVALUE(降順)
INCREMENT BY 増分値(負数で降順も可) 1
MINVALUE シーケンスの最小値 1(昇順)/ -(10^27)(降順)
MAXVALUE シーケンスの最大値 10^28 – 1(昇順)/ -1(降順)
CACHE n メモリにキャッシュする採番数 20
NOCACHE キャッシュしない(欠番が少ない)
CYCLE 最大値/最小値到達後に循環する NOCYCLE
ORDER 採番の順序を保証(RAC環境向け) NOORDER

作成例:基本的なシーケンス

SQL
-- 最もシンプルなシーケンス(デフォルト設定)
CREATE SEQUENCE emp_seq;

実行結果

Sequence created.

作成例:オプションを指定

SQL
-- 実務でよく使うシーケンス設定
CREATE SEQUENCE order_seq
  START WITH     1000
  INCREMENT BY   1
  MINVALUE       1000
  MAXVALUE       9999999
  CACHE          50
  NOCYCLE
  NOORDER;
降順シーケンスの作成例
SQL
-- 降順(デクリメント)のシーケンス
CREATE SEQUENCE countdown_seq
  START WITH     100
  INCREMENT BY   -1
  MINVALUE       1
  MAXVALUE       100
  NOCACHE
  NOCYCLE;
循環(CYCLE)シーケンスの作成例
SQL
-- 1〜12を繰り返す(月番号の生成等)
CREATE SEQUENCE month_seq
  START WITH     1
  INCREMENT BY   1
  MINVALUE       1
  MAXVALUE       12
  CACHE          12
  CYCLE;

シーケンスの使い方(NEXTVAL / CURRVAL)

シーケンスから値を取得するには、疑似カラムNEXTVALCURRVAL を使用します。

NEXTVAL:次の値を取得

NEXTVAL を呼び出すたびに、シーケンスの値がインクリメント(増分)されます。

SQL
-- 次の連番を取得
SELECT emp_seq.NEXTVAL FROM dual;

-- INSERT文で使用(最も一般的な使い方)
INSERT INTO employees (emp_id, emp_name, email)
VALUES (emp_seq.NEXTVAL, '山田太郎', 'yamada@example.com');

実行結果(SELECT)

   NEXTVAL
---------
        1

CURRVAL:現在の値を取得

CURRVAL は、同一セッションで最後に取得した NEXTVAL の値を返します。

SQL
-- 先にNEXTVALを呼び出す(必須)
SELECT emp_seq.NEXTVAL FROM dual;

-- 現在のセッションで最後に取得した値を確認
SELECT emp_seq.CURRVAL FROM dual;

注意:セッション開始後に一度も NEXTVAL を呼び出していない状態で CURRVAL を参照すると、ORA-08002: sequence EMP_SEQ.CURRVAL is not yet defined in this session エラーが発生します。

NEXTVAL / CURRVALが使える場所・使えない場所

場所 NEXTVAL CURRVAL
SELECT … FROM dual
INSERT文のVALUES句
INSERT文のSELECT句
UPDATE文のSET句
WHERE句 × ×
DEFAULT値 ×(12c以降は○) ×
CHECK制約 × ×
ビュー定義のSELECT × ×

実務での使用パターン

SQL
-- パターン1: 親子テーブルへの同時INSERT(CURRVALで同じIDを使う)
INSERT INTO orders (order_id, customer_id, order_date)
VALUES (order_seq.NEXTVAL, 101, SYSDATE);

INSERT INTO order_details (detail_id, order_id, product_id, qty)
VALUES (detail_seq.NEXTVAL, order_seq.CURRVAL, 501, 2);

-- パターン2: PL/SQLで変数に格納して使い回す
DECLARE
  v_id NUMBER;
BEGIN
  v_id := emp_seq.NEXTVAL;
  INSERT INTO employees (emp_id, emp_name) VALUES (v_id, '鈴木一郎');
  INSERT INTO emp_history (emp_id, action) VALUES (v_id, 'CREATED');
END;
/

シーケンスの変更(ALTER SEQUENCE)

既存のシーケンスの設定を変更するには ALTER SEQUENCE を使用します。

基本構文

構文
ALTER SEQUENCE シーケンス名
  [INCREMENT BY   新しい増分値]
  [MINVALUE       新しい最小値]
  [MAXVALUE       新しい最大値]
  [CACHE          新しいキャッシュ数 | NOCACHE]
  [CYCLE        | NOCYCLE]
  [ORDER        | NOORDER];

注意:ALTER SEQUENCE では START WITH は変更できません。開始値を変えたい場合は、シーケンスを DROP して再作成するか、後述のリセット方法を使用してください。

変更例

SQL
-- 増分値を変更
ALTER SEQUENCE emp_seq INCREMENT BY 5;

-- 最大値を変更
ALTER SEQUENCE emp_seq MAXVALUE 100000;

-- キャッシュサイズを変更
ALTER SEQUENCE emp_seq CACHE 100;

-- 循環を有効にする
ALTER SEQUENCE emp_seq CYCLE;

実行結果

Sequence altered.

シーケンスのリセット方法

シーケンスの値を特定の値にリセットしたい場面は実務でよくあります。Oracleにはリセット専用の構文がないため、いくつかの方法があります。

方法1:DROP & CREATE で再作成(推奨)

最もシンプルで確実な方法です。

SQL
-- 手順1: シーケンスを削除
DROP SEQUENCE emp_seq;

-- 手順2: 同じ名前で再作成(START WITHで開始値を指定)
CREATE SEQUENCE emp_seq
  START WITH 1
  INCREMENT BY 1
  NOCACHE;

注意:シーケンスを参照しているトリガーやプロシージャがある場合、DROP後にそれらは INVALID になります。再作成後に ALTER TRIGGER トリガー名 COMPILE; などで再コンパイルしてください。

方法2:INCREMENT BY を使ったリセット(DROPしない方法)

シーケンスをDROPしたくない場合(権限の問題やGRANTの再設定を避けたい場合)は、増分値を一時的に変更する方法が使えます。

SQL
-- 現在値が1050だとして、1にリセットしたい場合

-- 手順1: 現在値を確認
SELECT emp_seq.NEXTVAL FROM dual;  -- 結果: 1050

-- 手順2: 増分値を「-(現在値 - 目標値)」に設定
ALTER SEQUENCE emp_seq INCREMENT BY -1049;

-- 手順3: NEXTVALで目標値まで戻す
SELECT emp_seq.NEXTVAL FROM dual;  -- 結果: 1(1050 + (-1049) = 1)

-- 手順4: 増分値を元に戻す
ALTER SEQUENCE emp_seq INCREMENT BY 1;
PL/SQLで汎用的にリセットするプロシージャ
PL/SQL
CREATE OR REPLACE PROCEDURE reset_sequence(
  p_seq_name IN VARCHAR2,
  p_target   IN NUMBER DEFAULT 1
) AS
  v_current NUMBER;
  v_diff    NUMBER;
BEGIN
  EXECUTE IMMEDIATE
    'SELECT ' || p_seq_name || '.NEXTVAL FROM dual'
    INTO v_current;

  v_diff := p_target - v_current - 1;

  IF v_diff != 0 THEN
    EXECUTE IMMEDIATE
      'ALTER SEQUENCE ' || p_seq_name ||
      ' INCREMENT BY ' || v_diff;
    EXECUTE IMMEDIATE
      'SELECT ' || p_seq_name || '.NEXTVAL FROM dual'
      INTO v_current;
    EXECUTE IMMEDIATE
      'ALTER SEQUENCE ' || p_seq_name ||
      ' INCREMENT BY 1';
  END IF;
END;
/

-- 使用例
EXEC reset_sequence('EMP_SEQ', 1);

方法3:Oracle 18c以降の RESTART(推奨)

Oracle 18c以降では、ALTER SEQUENCE ... RESTART 構文で簡単にリセットできます。

SQL(Oracle 18c以降)
-- 初期値(START WITH値)にリセット
ALTER SEQUENCE emp_seq RESTART;

-- 指定した値からリスタート
ALTER SEQUENCE emp_seq RESTART START WITH 500;

ポイント:Oracle 18c以降を使っている場合は、RESTART が最も簡単で安全なリセット方法です。DROPせずに権限やGRANT設定もそのまま維持できます。

他のRDBMSとの比較

シーケンス関連の構文はRDBMSによって大きく異なります。

操作 Oracle PostgreSQL SQL Server
作成 CREATE SEQUENCE CREATE SEQUENCE CREATE SEQUENCE
削除 DROP SEQUENCE DROP SEQUENCE DROP SEQUENCE
次の値 seq.NEXTVAL nextval('seq') NEXT VALUE FOR seq
現在値 seq.CURRVAL currval('seq') なし(変数で保持)
リセット RESTART(18c〜) RESTART WITH RESTART WITH
IF EXISTS IF EXISTS(23c〜) IF EXISTS(9.1〜) IF EXISTS(2016〜)

MySQL には SEQUENCE がない

MySQLにはシーケンスオブジェクトがなく、代わりに AUTO_INCREMENT カラム属性を使います。

MySQL
-- MySQLでの連番生成(AUTO_INCREMENT)
CREATE TABLE employees (
  emp_id   INT AUTO_INCREMENT PRIMARY KEY,
  emp_name VARCHAR(100) NOT NULL
);

-- AUTO_INCREMENTのリセット
ALTER TABLE employees AUTO_INCREMENT = 1;
PostgreSQL でのシーケンス操作
PostgreSQL
-- シーケンスの作成
CREATE SEQUENCE emp_seq START WITH 1 INCREMENT BY 1;

-- 次の値を取得(関数形式)
SELECT nextval('emp_seq');

-- 現在値を取得
SELECT currval('emp_seq');

-- リセット
ALTER SEQUENCE emp_seq RESTART WITH 1;

-- 安全な削除
DROP SEQUENCE IF EXISTS emp_seq;
SQL Server でのシーケンス操作
SQL Server
-- シーケンスの作成
CREATE SEQUENCE dbo.emp_seq
  START WITH 1
  INCREMENT BY 1;

-- 次の値を取得
SELECT NEXT VALUE FOR dbo.emp_seq;

-- リセット
ALTER SEQUENCE dbo.emp_seq RESTART WITH 1;

-- 安全な削除(SQL Server 2016以降)
DROP SEQUENCE IF EXISTS dbo.emp_seq;

よくあるエラーと対処法

シーケンス操作で発生しやすいエラーを一覧にまとめます。

エラーコード メッセージ 原因 対処法
ORA-02289 sequence does not exist 指定したシーケンスが存在しない シーケンス名・スキーマを確認
ORA-08002 CURRVAL is not yet defined セッション内でNEXTVAL未実行 先にNEXTVALを呼び出す
ORA-08004 sequence exceeds MAXVALUE MAXVALUEに到達(NOCYCLE時) MAXVALUEを増やすかCYCLEに変更
ORA-02283 cannot alter starting sequence number ALTER SEQUENCEでSTART WITHを変更 DROPして再作成、またはRESTART
ORA-01722 invalid number シーケンス値を文字列カラムに使用 TO_CHARで型変換する
ORA-01031 insufficient privileges シーケンスの操作権限がない GRANT SELECT ON seq TO ユーザー

ORA-02289 の詳細と対処

最も頻繁に発生するエラーです。

エラー再現と対処
-- エラー発生例
SELECT nonexistent_seq.NEXTVAL FROM dual;
-- ORA-02289: sequence does not exist

-- 対処1: シーケンスの存在を確認
SELECT sequence_name
FROM user_sequences
WHERE sequence_name = 'NONEXISTENT_SEQ';

-- 対処2: 他のスキーマの場合はスキーマ名を指定
SELECT hr.emp_seq.NEXTVAL FROM dual;

-- 対処3: シノニムを確認
SELECT synonym_name, table_owner, table_name
FROM user_synonyms
WHERE synonym_name = 'EMP_SEQ';

ORA-08004 の詳細と対処

エラー再現と対処
-- MAXVALUE到達でエラー
-- ORA-08004: sequence SMALL_SEQ.NEXTVAL exceeds MAXVALUE

-- 対処1: MAXVALUEを増やす
ALTER SEQUENCE small_seq MAXVALUE 999999999;

-- 対処2: 最大値の制限を撤廃
ALTER SEQUENCE small_seq NOMAXVALUE;

-- 対処3: 循環を有効にする(用途に応じて)
ALTER SEQUENCE small_seq CYCLE;

実務でのベストプラクティス

シーケンスを本番環境で運用する際のポイントをまとめます。

1. 命名規則を統一する

命名パターン 説明
テーブル名_SEQ EMPLOYEES_SEQ 最も一般的
SEQ_テーブル名 SEQ_EMPLOYEES プレフィックス型
テーブル名_カラム名_SEQ EMPLOYEES_EMP_ID_SEQ カラムまで特定

2. CACHEの設定を最適化する

CACHEの使い分け

  • CACHE 20(デフォルト):通常のOLTP処理に適切
  • CACHE 100〜1000:大量INSERT(バッチ処理)時のパフォーマンス向上
  • NOCACHE:欠番を最小限にしたい場合(ただしパフォーマンスが低下)
  • キャッシュされた値はインスタンス障害時に失われ、欠番の原因になります

3. シーケンスの権限管理

SQL
-- 他のユーザーにシーケンスの使用を許可
GRANT SELECT ON emp_seq TO app_user;

-- シノニムを作成して他スキーマからシンプルにアクセス
CREATE SYNONYM emp_seq FOR hr.emp_seq;

-- 権限を取り消す
REVOKE SELECT ON emp_seq FROM app_user;

4. Oracle 12c以降のIDENTITYカラム

Oracle 12c以降では、テーブルカラムに直接連番を設定できる IDENTITY が追加されました。内部的にはシーケンスが自動作成されます。

SQL(Oracle 12c以降)
-- IDENTITYカラム(12c以降推奨)
CREATE TABLE employees (
  emp_id   NUMBER GENERATED ALWAYS AS IDENTITY,
  emp_name VARCHAR2(100) NOT NULL
);

-- オプション付きIDENTITY
CREATE TABLE orders (
  order_id NUMBER GENERATED BY DEFAULT AS IDENTITY
    (START WITH 1000 INCREMENT BY 1),
  customer_id NUMBER NOT NULL
);
種類 手動指定 用途
GENERATED ALWAYS 不可(必ず自動採番) 厳密にシステムが管理する連番
GENERATED BY DEFAULT 可能(省略時のみ自動採番) データ移行時に手動値も入れたい場合
GENERATED BY DEFAULT ON NULL NULL指定時のみ自動採番 NULLを渡した場合にも自動採番

シーケンス操作のまとめ

操作 SQL構文
作成 CREATE SEQUENCE seq_name START WITH 1 INCREMENT BY 1
削除 DROP SEQUENCE seq_name
次の値を取得 SELECT seq_name.NEXTVAL FROM dual
現在値を取得 SELECT seq_name.CURRVAL FROM dual
設定変更 ALTER SEQUENCE seq_name INCREMENT BY 5
リセット(18c〜) ALTER SEQUENCE seq_name RESTART START WITH 1
一覧確認 SELECT * FROM user_sequences
依存関係確認 SELECT * FROM user_dependencies WHERE referenced_type = 'SEQUENCE'

まとめ

項目 内容
シーケンスの削除 DROP SEQUENCE シーケンス名 で削除(DDL、暗黙コミット)
削除前の確認 USER_DEPENDENCIES で参照元オブジェクトを確認
シーケンスの確認 USER_SEQUENCES / ALL_SEQUENCES ビューで一覧・設定を確認
値の取得 NEXTVAL(次の値)/ CURRVAL(現在値)
リセット方法 DROP & CREATE、INCREMENT BY操作、RESTART(18c以降)
よくあるエラー ORA-02289(存在しない)、ORA-08002(CURRVAL未定義)、ORA-08004(MAXVALUE超過)
12c以降の推奨 単純な連番には IDENTITY カラムが便利

シーケンスはOracleの基本オブジェクトですが、キャッシュによる欠番DDLの暗黙コミットDROP時の依存関係など、実務で注意すべきポイントが多くあります。特に本番環境でDROP SEQUENCEを実行する場合は、事前に参照元オブジェクトを確認し、影響範囲を把握してから実行しましょう。