Oracle Databaseを運用していると、「更新前のデータを今すぐ確認したい」「いつの間にか消えたレコードの内容を調べたい」という場面に遭遇します。そんな時に役立つのが、過去の時点を指定してデータを参照できる「フラッシュバッククエリ(Flashback Query)」です。
この記事では、正確な制御が可能な SCN(システム変更番号) 指定と、直感的に分かりやすい TIMESTAMP(日時) 指定の両方の手法を解説します。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
◆ フラッシュバッククエリとは?
通常の SELECT 文は「現在」の確定したデータを取得しますが、フラッシュバッククエリは UNDO(変更前)データ を参照することで、過去の任意の時点の状態を映し出します。
- SCN指定: データベースの内部的な順序番号で指定。最も正確。
- 日時指定: 「5分前」や「特定の時刻」など、人間にとって扱いやすい。
◆ 基本構文
SCNを指定する場合
SELECT ... FROM テーブル名 AS OF SCN SCN番号;
例:SCN「1234567」時点の内容を確認する
SELECT * FROM emp AS OF SCN 1234567;
日時(TIMESTAMP)を指定する場合
SELECT ... FROM テーブル名 AS OF TIMESTAMP 日時表現;
◆ 実践:フラッシュバッククエリを試してみよう
テスト用テーブルを作成し、更新操作の前後でデータを比較する実験を行います。
① テーブル作成・初期データ投入
CREATE TABLE emp_test (
empno NUMBER PRIMARY KEY,
ename VARCHAR2(10)
);
INSERT INTO emp_test VALUES (1001, 'TARO');
INSERT INTO emp_test VALUES (1002, 'JIRO');
COMMIT;
② リカバリポイント(現在のSCNと日時)を取得
更新前の「戻りたい地点」の情報を取得し、メモしておきます。
SELECT dbms_flashback.get_system_change_number AS current_scn,
SYSTIMESTAMP AS current_time
FROM dual;
- 例: SCN
2283755/ 時刻2025-03-22 15:01:00
③ データの更新(ミスを再現)
UPDATE emp_test SET ename = 'SABURO' WHERE empno = 1002;
COMMIT;
-- 現在のデータは SABURO になっている
SELECT * FROM emp_test;
④ フラッシュバッククエリで「過去」を参照
更新前のデータを2つの方法で参照してみましょう。
1. SCNを指定して参照
SELECT * FROM emp_test AS OF SCN 2283755;
2. 日時を指定して参照
SELECT * FROM emp_test AS OF TIMESTAMP TO_TIMESTAMP('2025-03-22 15:01:00', 'YYYY-MM-DD HH24:MI:SS');
結果:
どちらのクエリでも、現在は SABURO になっている箇所が、更新前の JIRO として表示されます。
SQL> CREATE TABLE emp_test (
2 empno NUMBER PRIMARY KEY,
3 ename VARCHAR2(10)
4 );
表が作成されました。
SQL> INSERT INTO emp_test VALUES (1001, 'TARO');
1行が作成されました。
SQL> INSERT INTO emp_test VALUES (1002, 'JIRO');
1行が作成されました。
SQL> SELECT * FROM emp_test;
EMPNO ENAME
---------- ------------------------------
1001 TARO
1002 JIRO
SQL> commit;
コミットが完了しました。
SQL> SELECT dbms_flashback.get_system_change_number AS current_scn FROM dual;
CURRENT_SCN
-----------
2283755 ★
SQL> UPDATE emp_test SET ename = 'SABURO' WHERE empno = 1002;
1行が更新されました。
SQL> SELECT * FROM emp_test;
EMPNO ENAME
---------- ------------------------------
1001 TARO
1002 SABURO
SQL> commit;
コミットが完了しました。
SQL> SELECT * FROM emp_test AS OF SCN 2283755; ★UPDATE前の時点のSCNを指定
EMPNO ENAME
---------- ------------------------------
1001 TARO
1002 JIRO
◆ 時系列イメージ図
過去への参照は、以下のように時間軸を遡ってUNDOセグメントを読み取ります。
時系列 ─────────────→
[SCN:2283755] [SCN:2283800]
[時:15:01:00] [時:15:05:00]
↓ ↓
+----------+ +------------+
| 1002:JIRO| ──更新──→ | 1002:SABURO|
+----------+ +------------+
クエリ実行:
SELECT * FROM emp_test AS OF SCN 2283755;
→ 結果は「JIRO」が返る!
◆ FAQ
Q: フラッシュバッククエリでデータを参照できる期間に制限はありますか?
A: はい、初期化パラメータ UNDO_RETENTION で設定された秒数に依存します。ただし、UNDO表領域のサイズが不足すると、設定時間内であってもデータが上書きされ、参照できなくなる(ORA-01555発生)場合があります。
Q: SCNとTIMESTAMPのどちらを使うべきですか?
A: アプリケーションのロジックや正確なトラブル調査には SCN が推奨されます。一方で、管理者が手動で「数分前の状態」をサクッと確認したい場合には、直感的な TIMESTAMP が便利です。
Q: 削除してしまったテーブル自体をフラッシュバッククエリで参照できますか?
A: いいえ、テーブル自体が DROP された場合はフラッシュバッククエリを実行できません。その場合は FLASHBACK TABLE ... TO BEFORE DROP(Flashback Drop機能)を使用してください。
Q: フラッシュバッククエリを実行するとパフォーマンスに影響しますか?
A: 現在のデータブロックを読み取る代わりにUNDOセグメントを読み取るため、大量の過去データを参照する場合や、UNDOセグメントが大量に生成されている環境では、通常のクエリより負荷が高くなる可能性があります。
◆ 運用上の注意点
- UNDO保持期間(undo_retention)の制限フラッシュバッククエリはUNDOデータに依存します。保持期間を過ぎて情報が上書きされると、
ORA-01555: snapshot too oldエラーが発生し、参照できなくなります。 - TIMESTAMPの精度日時指定の場合、内部的には約3秒間隔でSCNにマッピングされるため、1秒単位の極めて厳密な指定が必要な場合はSCNを使用してください。
- タイムゾーンの考慮
AS OF TIMESTAMPを使う際はタイムゾーンの乖離に注意が必要です。基本的にはSYSTIMESTAMPを基準に計算するのが安全です。
◆ まとめ
| 項目 | 内容 |
| フラッシュバッククエリ | 過去のデータを SELECT で簡単に参照できる強力な機能。 |
| AS OF SCN | 変更時点を正確にピンポイントで指定して調査できる。 |
| AS OF TIMESTAMP | 「◯分前」など、時刻ベースで直感的に指定できる。 |
| 重要な前提 | UNDOデータが保持されている必要がある(undo_retentionの設定)。 |
本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。
[参考]
Oracle Flashback Technologyの使用


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


コメント