【Oracle】シーケンスの確認方法完全ガイド|USER/ALL/DBA_SEQUENCES・NEXTVAL/CURRVAL・依存オブジェクト調査まで解説

【Oracle】シーケンスの確認方法完全ガイド|USER/ALL/DBA_SEQUENCES・NEXTVAL/CURRVAL・依存オブジェクト調査まで解説 Oracle

「このシーケンス、今いくつまで進んでいるんだろう」――そう思ったとき、うっかり NEXTVAL を実行してしまうと値が増えてしまいます。また、USER_SEQUENCESLAST_NUMBER を見ても、キャッシュが有効だと実際の採番済み番号と一致しないケースもあります。

さらに「別スキーマのシーケンスが見えない」「シーケンスを削除したらトリガーが壊れた」など、確認方法を知らないことで起きる事故は少なくありません。

この記事では、USER_SEQUENCES / ALL_SEQUENCES / DBA_SEQUENCES の使い分けから、値を増やさずに現在値を確認する方法依存オブジェクトの調査上限監視 SQL まで、実務で必要なシーケンス確認の知識をすべて解説します。

この記事でわかること
・USER_SEQUENCES / ALL_SEQUENCES / DBA_SEQUENCES の違いと使い分け
・各ビューの列(MIN_VALUE・MAX_VALUE・CACHE_SIZE・CYCLE_FLAG など)の意味
・NEXTVAL / CURRVAL で現在値を確認する方法と注意点
・LAST_NUMBER が「実際の現在値」と異なる理由
・USER_DEPENDENCIES でシーケンスを使っているオブジェクトを調べる方法
・シーケンスが上限に近づいていないか監視する SQL
スポンサーリンク

Oracleのシーケンスとは

シーケンス(SEQUENCE)は、一意な連番を自動生成するオブジェクトです。主にテーブルの主キー(ID列)を採番するために使われます。

特徴 説明
テーブルと独立 シーケンスはテーブルに紐づかない独立したオブジェクト
複数テーブルで共有可能 1つのシーケンスを複数のテーブルで使える
値は自動採番 NEXTVAL を呼ぶたびに定義した増分で値が増える
ロールバックしても値は戻らない トランザクションをロールバックしても採番済みの値は消費される
シーケンスの確認が必要になる場面
・主キーが重複エラーになったとき(シーケンスが想定より進んでいないか確認)
・データ移行後にシーケンスをリセットしたいとき
・どのシーケンスが存在するか棚卸ししたいとき
・シーケンスの設定(最大値・キャッシュ・CYCLE設定)を確認したいとき

USER_SEQUENCES:自分が所有するシーケンスを確認する

USER_SEQUENCES は、現在接続しているユーザーが所有するシーケンスだけを表示するビューです。最もよく使うビューです。

SQL
SELECT * FROM USER_SEQUENCES ORDER BY SEQUENCE_NAME;

全列が多すぎると感じる場合は、よく使う列に絞って確認します。

SQL(よく使う列に絞る)
SELECT
    SEQUENCE_NAME,
    MIN_VALUE,
    MAX_VALUE,
    INCREMENT_BY,
    CYCLE_FLAG,
    ORDER_FLAG,
    CACHE_SIZE,
    LAST_NUMBER
FROM USER_SEQUENCES
ORDER BY SEQUENCE_NAME;

USER_SEQUENCES の主要列の意味

列名 意味 備考
SEQUENCE_NAME シーケンスの名前
MIN_VALUE 最小値 デフォルト: 1
MAX_VALUE 最大値 デフォルト: 9999999999999999999999999999
INCREMENT_BY 1回のNEXTVALで増える量 デフォルト: 1(負値で減算シーケンスも可)
CYCLE_FLAG MAX値到達後に最小値から再開するか Y: 再開する / N: エラー
ORDER_FLAG 採番の順序保証(RAC環境) Y: 順序保証 / N: 保証しない
CACHE_SIZE メモリにキャッシュする値の個数 0: キャッシュなし、デフォルト20
LAST_NUMBER 次にディスクに書き込まれる予定の値 ※実際の現在値とは異なる場合がある(後述)
LAST_NUMBER の罠:実際の現在値と一致しない
キャッシュ(CACHE_SIZE > 0)が有効な場合、LAST_NUMBER は「次にディスクに書き込まれる予定の値」であり、実際に採番済みの最後の値ではありません。
たとえば CACHE_SIZE=20 のシーケンスで NEXTVAL を2回呼んだ場合、LAST_NUMBER は 21(20件分キャッシュした先)を指しており、実際の「最後に払い出した値」は 2 です。
さらにデータベースが再起動すると、キャッシュされた値は失われるため、再起動後は最大で CACHE_SIZE 分の値が欠番になることがあります。

ALL_SEQUENCES:他ユーザーのシーケンスも確認する

ALL_SEQUENCES は、現在のユーザーが参照権限を持つすべてのシーケンスを表示します。USER_SEQUENCES と異なり SEQUENCE_OWNER 列があり、誰のシーケンスかを確認できます。

SQL(すべて表示)
SELECT
    SEQUENCE_OWNER,
    SEQUENCE_NAME,
    MIN_VALUE,
    MAX_VALUE,
    INCREMENT_BY,
    LAST_NUMBER
FROM ALL_SEQUENCES
ORDER BY SEQUENCE_OWNER, SEQUENCE_NAME;

特定のスキーマ(ユーザー)に絞り込む場合は SEQUENCE_OWNER で絞ります。

SQL(スキーマを指定)
SELECT
    SEQUENCE_NAME,
    MIN_VALUE,
    MAX_VALUE,
    INCREMENT_BY,
    CACHE_SIZE,
    LAST_NUMBER
FROM ALL_SEQUENCES
WHERE SEQUENCE_OWNER = 'SCOTT'
ORDER BY SEQUENCE_NAME;
ALL_SEQUENCES でシーケンスが見えない場合、そのシーケンスへの SELECT 権限がありません。権限の確認方法は【Oracle】ユーザ権限を確認する方法完全ガイドを参照してください。

DBA_SEQUENCES:データベース全体のシーケンスを確認する

DBA_SEQUENCES は、データベースに存在するすべてのシーケンスを確認できるビューです。ただし DBA 権限または SELECT ANY DICTIONARY 権限が必要です。

SQL
SELECT
    SEQUENCE_OWNER,
    SEQUENCE_NAME,
    MIN_VALUE,
    MAX_VALUE,
    INCREMENT_BY,
    CYCLE_FLAG,
    CACHE_SIZE,
    LAST_NUMBER
FROM DBA_SEQUENCES
ORDER BY SEQUENCE_OWNER, SEQUENCE_NAME;
ビュー名 確認できる範囲 必要な権限
USER_SEQUENCES 自分が所有するシーケンスのみ なし(誰でも使える)
ALL_SEQUENCES 自分が参照権限を持つシーケンス なし(権限を持つ範囲まで)
DBA_SEQUENCES データベース内の全シーケンス DBA権限 or SELECT ANY DICTIONARY

特定のシーケンスを指定して確認する

シーケンス名がわかっている場合は WHERE で絞り込みます。

SQL(シーケンス名で絞り込む)
SELECT
    SEQUENCE_NAME,
    MIN_VALUE,
    MAX_VALUE,
    INCREMENT_BY,
    CYCLE_FLAG,
    ORDER_FLAG,
    CACHE_SIZE,
    LAST_NUMBER
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = 'SEQ_EMP';

シーケンス名の一部しかわからない場合は LIKE で検索します。

SQL(LIKE検索)
SELECT SEQUENCE_NAME, LAST_NUMBER, INCREMENT_BY
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME LIKE 'SEQ%'
ORDER BY SEQUENCE_NAME;
シーケンス名は大文字で格納されている
Oracleのオブジェクト名は引用符なしで作成すると内部的にすべて大文字で格納されます。WHERE SEQUENCE_NAME = 'seq_emp'(小文字)では一致しないため、検索時は大文字で指定してください。

NEXTVAL・CURRVALで現在値を確認する

データディクショナリビュー以外に、SQL で直接シーケンスの値を取得する方法もあります。

NEXTVAL:次の値を取得する(値が進む)

NEXTVAL は呼ぶたびに値が増える
NEXTVAL を呼ぶと、シーケンスは INCREMENT_BY 分だけ進みます。「確認したいだけ」なのに NEXTVAL を使うと採番済みの番号が飛んでしまいます。値を増やさずに確認したい場合は CURRVAL を使ってください。
SQL(NEXTVAL:次の値を取得 ※値が進む)
SELECT SEQ_EMP.NEXTVAL FROM DUAL;

CURRVAL:現在値を確認する(値が進まない)

CURRVAL は現在のセッションで 最後に取得した NEXTVAL の値を返します。値は進みません。

SQL(CURRVAL:現在値を確認 ※値が進まない)
SELECT SEQ_EMP.CURRVAL FROM DUAL;
CURRVAL はセッション内で NEXTVAL を一度も呼んでいないと使えない
シーケンスを作成した直後や、接続し直した後など、そのセッションで一度も NEXTVAL を呼んでいない状態で CURRVAL を実行すると ORA-08002: シーケンスSEQ_EMP.CURRVALはこのセッションでは定義されていません エラーになります。

別スキーマのシーケンスを確認する

SQL(スキーマ名を指定)
-- 別スキーマのシーケンスを参照する場合
SELECT SCOTT.SEQ_EMP.NEXTVAL FROM DUAL;
SELECT SCOTT.SEQ_EMP.CURRVAL FROM DUAL;

シーケンスを使っているオブジェクトを調べる

あるシーケンスがどのトリガー・ストアドプロシージャ・ビューなどで使われているかは USER_DEPENDENCIES で確認できます。

SQL(USER_DEPENDENCIES でシーケンスへの依存を検索)
SELECT
    NAME         AS object_name,
    TYPE         AS object_type,
    REFERENCED_NAME  AS seq_name,
    REFERENCED_TYPE  AS ref_type
FROM USER_DEPENDENCIES
WHERE REFERENCED_TYPE = 'SEQUENCE'
ORDER BY TYPE, NAME;

特定のシーケンスを参照しているオブジェクトに絞る場合は REFERENCED_NAME で絞ります。

SQL(特定シーケンスへの依存を調べる)
SELECT
    NAME         AS object_name,
    TYPE         AS object_type
FROM USER_DEPENDENCIES
WHERE REFERENCED_TYPE = 'SEQUENCE'
  AND REFERENCED_NAME = 'SEQ_EMP'
ORDER BY TYPE, NAME;
シーケンスを変更・削除する前に依存オブジェクトを確認する
シーケンスを DROP または ALTER する前に上記 SQL で依存オブジェクトを確認しておくと、変更後に関連トリガーやプロシージャが壊れるリスクを事前に把握できます。シーケンスの削除・変更については【Oracle】シーケンスの削除・作成・変更方法を参照してください。

シーケンスが上限に近づいていないか確認する

長期運用しているシステムでは、シーケンスが MAX_VALUE に近づいていないか定期的に確認することが重要です。CYCLE_FLAG = 'N'(デフォルト)の場合、MAX_VALUE に達すると ORA-08004 エラーが発生してシステムが止まります。

SQL(上限までの残件数を確認)
SELECT
    SEQUENCE_NAME,
    LAST_NUMBER,
    MAX_VALUE,
    (MAX_VALUE - LAST_NUMBER) AS remaining,
    ROUND((LAST_NUMBER / MAX_VALUE) * 100, 2) AS used_pct
FROM USER_SEQUENCES
ORDER BY used_pct DESC;
SQL(使用率が80%を超えているシーケンスを抽出)
SELECT
    SEQUENCE_NAME,
    LAST_NUMBER,
    MAX_VALUE,
    ROUND((LAST_NUMBER / MAX_VALUE) * 100, 2) AS used_pct
FROM USER_SEQUENCES
WHERE CYCLE_FLAG = 'N'
  AND ROUND((LAST_NUMBER / MAX_VALUE) * 100, 2) >= 80
ORDER BY used_pct DESC;
MAX_VALUE に達する前に対処する
シーケンスの上限を拡張するには ALTER SEQUENCE シーケンス名 MAXVALUE 新しい上限値; で変更できます。変更手順の詳細は【Oracle】シーケンスの変更方法を参照してください。

シーケンスの現在値を確認した後の操作

シーケンスの確認後、値を進めたい・リセットしたい場合は以下の記事を参照してください。

よくある質問

USER_SEQUENCES の LAST_NUMBER が実際の現在値と違うのはなぜですか?
キャッシュ(CACHE_SIZE)が有効な場合、LAST_NUMBER はキャッシュ分を先取りした「次にディスクに書き込まれる値」を示しています。たとえば CACHE_SIZE=20、現在値が 1 の場合、LAST_NUMBER は 21 になります。実際に最後に払い出した値を正確に知りたい場合は CURRVAL(※セッション内で NEXTVAL を呼んでいる場合のみ有効)か、そのシーケンスを使っているテーブルの最大 ID を確認するほうが確実です。
DBA_SEQUENCES を参照しようとすると「表またはビューが存在しません」エラーが出ます
DBA_SEQUENCES の参照には DBA ロール または SELECT ANY DICTIONARY システム権限が必要です。一般ユーザーには付与されていないことが多いため、その場合は ALL_SEQUENCES を使ってください。権限の確認方法は【Oracle】ユーザ権限を確認する方法完全ガイドを参照してください。
CURRVAL を実行すると ORA-08002 エラーが出ます
CURRVAL は、同一セッション内でそのシーケンスの NEXTVAL を一度も呼んでいないと使用できません。接続直後やシーケンス作成直後に CURRVAL を呼ぶとこのエラーになります。まず NEXTVAL を1回呼んで値を初期化してから CURRVAL を使ってください。
シーケンス名でLIKE検索しても見つかりません
Oracleのオブジェクト名は引用符なしで作成した場合、内部的にすべて大文字で格納されます。LIKE '%seq%'(小文字)ではヒットしないため、LIKE '%SEQ%'(大文字)で検索してください。
別スキーマのシーケンスを確認したいのですが ALL_SEQUENCES に表示されません
そのシーケンスへの SELECT 権限がない可能性があります。GRANT SELECT ON スキーマ名.シーケンス名 TO あなたのユーザー名; で権限を付与してもらうか、DBA権限がある場合は DBA_SEQUENCES を使って確認してください。
シーケンスと IDENTITY 列の違いは何ですか?
Oracle 12c 以降では GENERATED AS IDENTITY を使ったIDENTITY列が利用できます。IDENTITY列はテーブル列に直接定義され、内部的にはシーケンスが自動生成されます。このシステム生成シーケンスも USER_SEQUENCESISEQ$$_ で始まる名前で確認できます。手動でシーケンスを作成・管理したい場合や複数テーブルで採番を共有したい場合は従来のシーケンスを使います。
シーケンスの現在値を確認するだけで変更はしたくないのですが
ビュー(USER_SEQUENCES)で LAST_NUMBER を参照するか、同一セッション内で直前に NEXTVAL を呼んでいれば CURRVAL で確認できます。「現在値を正確に知りたい+値は進めたくない」という場合は、そのシーケンスを使っているテーブルの最大 ID 値を確認するのが最も確実です。例: SELECT MAX(emp_id) FROM emp; のようにテーブルの実データから確認できます。

まとめ

Oracleのシーケンス確認方法を整理します。

目的 使うビュー / 方法
自分のシーケンスを一覧確認する USER_SEQUENCES
他スキーマを含め参照できるシーケンスを確認する ALL_SEQUENCES(SEQUENCE_OWNER で絞り込み)
データベース全体のシーケンスを確認する(要DBA権限) DBA_SEQUENCES
次の値を取得する(値が進む) SEQ名.NEXTVAL FROM DUAL
現在値を確認する(値が進まない) SEQ名.CURRVAL FROM DUAL(要: 同セッションで NEXTVAL 済み)
シーケンスを使っているオブジェクトを調べる USER_DEPENDENCIES(REFERENCED_TYPE = ‘SEQUENCE’)
上限までの残件数を確認する MAX_VALUE – LAST_NUMBER を計算

シーケンスの確認でよくある落とし穴は、LAST_NUMBER がキャッシュ分を先取りしており実際の現在値と異なる点と、CURRVAL がセッション内で NEXTVAL を呼ばないと使えない点です。確認の目的に応じてビューと関数を使い分けてください。