Oracle Databaseを運用していると、「いつ、どのトランザクションで、データがどう書き換えられたのか」という履歴を追跡したい場面があります。そんな時に役立つのがフラッシュバックバージョン問い合わせ(Flashback Version Query)です。
この機能を使えば、特定の行に対して過去に行われた挿入・更新・削除の変遷を、SCNや時間軸に沿って一覧表示できます。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
1. フラッシュバックバージョン問い合わせとは?
フラッシュバックバージョン問い合わせは、UNDOデータを利用して特定の期間(SCNまたは日時)内に発生した行レベルの変更履歴を表示する機能です。通常の SELECT 文に VERSIONS BETWEEN 句を加えるだけで、変更の「開始点」「終了点」「操作内容(I/U/D)」をメタデータとともに取得できます。
2. 事前準備:テスト用テーブルの作成と履歴生成
実際に履歴を確認するために、テーブルを作成して複数回の更新を行ってみましょう。
① テーブル作成と初期データ投入
-- テスト用表の作成
CREATE TABLE emp_flash (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(50),
salary NUMBER
);
-- 初期データの投入
INSERT INTO emp_flash VALUES (1, 'TARO', 300000);
COMMIT;
② リカバリポイント(現在のSCN)の確認
更新前の開始点となるSCNをメモしておきます。
-- 現在のSCNの確認
SELECT CURRENT_SCN FROM V$DATABASE;
-- 例: 2284694
③ データの更新とコミット
あえて複数回に分けてコミットし、変更履歴を生成します。
-- 1回目の更新
UPDATE emp_flash SET salary = 320000 WHERE emp_id = 1;
COMMIT;
-- 2回目の更新
UPDATE emp_flash SET salary = 350000 WHERE emp_id = 1;
COMMIT;
-- 3回目の更新
UPDATE emp_flash SET salary = 400000 WHERE emp_id = 1;
COMMIT;
-- 最終時点のSCNを確認
SELECT CURRENT_SCN FROM V$DATABASE;
-- 例: 2284735
3. 履歴の確認(SCN指定)
VERSIONS BETWEEN SCN を使用して、指定したSCNの範囲内でデータがどう変わったかを確認します。
SELECT
emp_id,
emp_name,
salary,
VERSIONS_STARTSCN, -- 変更が有効になった開始SCN
VERSIONS_ENDSCN, -- 変更が上書きされた終了SCN
VERSIONS_XID, -- トランザクションID
VERSIONS_OPERATION -- 操作種別 (I:Insert, U:Update, D:Delete)
FROM
emp_flash VERSIONS BETWEEN SCN 2284694 AND 2284735
WHERE
emp_id = 1;
SQL> CREATE TABLE emp_flash (
2 emp_id NUMBER PRIMARY KEY,
3 emp_name VARCHAR2(50),
4 salary NUMBER
5 );
表が作成されました。
SQL> INSERT INTO emp_flash VALUES (1, 'TARO', 300000);
1行が作成されました。
SQL> col emp_name for a20
SQL> SELECT * FROM emp_flash;
EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 300000
SQL> commit;
コミットが完了しました。
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
2284694
SQL> UPDATE emp_flash SET salary = 320000 WHERE emp_id = 1;
1行が更新されました。
SQL> SELECT * FROM emp_flash;
EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 320000
SQL> commit;
コミットが完了しました。
SQL> UPDATE emp_flash SET salary = 350000 WHERE emp_id = 1;
1行が更新されました。
SQL> SELECT * FROM emp_flash;
EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 350000
SQL> commit;
コミットが完了しました。
SQL> UPDATE emp_flash SET salary = 400000 WHERE emp_id = 1;
1行が更新されました。
SQL> SELECT * FROM emp_flash;
EMP_ID EMP_NAME SALARY
---------- -------------------- ----------
1 TARO 400000
SQL> commit;
コミットが完了しました。
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
2284735
SQL> SELECT
2 emp_id,
3 emp_name,
4 salary,
5 VERSIONS_STARTSCN,
6 VERSIONS_ENDSCN,
7 VERSIONS_XID,
8 VERSIONS_OPERATION
9 FROM
10 emp_flash VERSIONS BETWEEN SCN 2284694 AND 2284735
11 WHERE
12 emp_id = 1;
EMP_ID EMP_NAME SALARY VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_XID VER
---------- -------------------- ---------- ----------------- --------------- ---------------- ---
1 TARO 400000 2284723 09000700F1030000 U
1 TARO 350000 2284710 2284723 08000C000E040000 U
1 TARO 320000 2284702 2284710 0A001A00FE030000 U
1 TARO 300000 2284702
実行結果のイメージ
| EMP_ID | EMP_NAME | SALARY | VERSIONS_STARTSCN | VERSIONS_ENDSCN | VERSIONS_OPERATION |
| 1 | TARO | 400000 | 2284723 | U | |
| 1 | TARO | 350000 | 2284710 | 2284723 | U |
| 1 | TARO | 320000 | 2284702 | 2284710 | U |
| 1 | TARO | 300000 | 2284702 |
4. 日時で履歴を指定する方法(補足)
SCNの代わりに、人間にわかりやすい日時(TIMESTAMP)で指定することも可能です。
SELECT
emp_id,
emp_name,
salary,
VERSIONS_STARTTIME,
VERSIONS_ENDTIME,
VERSIONS_OPERATION
FROM
emp_flash VERSIONS BETWEEN TIMESTAMP
TO_TIMESTAMP('2025-03-22 10:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND
TO_TIMESTAMP('2025-03-22 11:00:00', 'YYYY-MM-DD HH24:MI:SS')
WHERE
emp_id = 1;
5. FAQ
Q: VERSIONS_STARTSCN が null になっている行があるのはなぜですか?
A: その行の変更が、指定した BETWEEN 範囲よりも前に行われた場合に null となります。
Q: VERSIONS_OPERATION で取得できる文字の意味を教えてください。
A: I は INSERT、U は UPDATE、D は DELETE を示します。
Q: どのくらい前の履歴まで遡ることができますか?
A: UNDO表領域のサイズと UNDO_RETENTION パラメータの設定に依存します。これらを超えてデータが上書きされると参照できません。
Q: DDL(テーブル定義変更)を行った後の履歴はどうなりますか?
A: テーブル定義の変更を跨いでバージョン問い合わせを行うと、エラーが発生するか、正しい結果が得られない場合があります。
6. まとめ
| 項目 | 内容 |
| 主な用途 | データの誤更新調査、監査、トラブルシューティング |
| 必要なデータ | UNDOデータ(UNDO表領域に依存) |
| 指定方法 | SCN(システム変更番号)または TIMESTAMP(日時) |
| 取得情報 | 変更前後の値、トランザクションID、操作種別(I/U/D) |
フラッシュバックバージョン問い合わせは、特定のデータの「犯人探し」や「変遷の確認」に最適な機能です。本番環境で不審なデータを見つけた際は、まずこのクエリで歴史を紐解いてみましょう。
本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。
[参考]
Oracle Flashback Technologyの使用


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


コメント