OracleでDROP操作を安全に制御!

SQL

自律トランザクションでログ記録するDDLトリガーの構築手順

重要なテーブルを誤ってDROPしてしまう…。
そんな悲劇を防ぎつつ、操作ログも残したいというニーズに応えるのが「DDLトリガー+自律トランザクション」の組み合わせです。

この記事では、ログ記録を別スキーマに逃がす構成でORA-600などのリスクを避けつつ、確実にDROP操作をブロックして監査ログも残す方法を紹介します。

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

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


🗂構成概要

+----------------------+                  +--------------------------+
| USER_A | | AUDIT_USER |
| (操作対象) | | (ログ保存専用) |
| - EMPなどの表 | →DROP操作検知→ | - DDL_BLOCK_LOG表 |
| - DDLトリガー | ←INSERTログ記録 | |
+----------------------+ +--------------------------+

🧾手順

① ログ保存用スキーマ AUDIT_USER を作成(DBAで)

CREATE USER audit_user IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;

GRANT CONNECT, RESOURCE TO audit_user;

② ログ用テーブルを作成(AUDIT_USERで)

CONNECT audit_user/password

CREATE TABLE ddl_block_log (
obj_name VARCHAR2(100),
event VARCHAR2(20),
log_time DATE
);

③ 操作対象ユーザー USER_A を作成(DBAで)

CREATE USER user_a IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;

GRANT CONNECT, RESOURCE TO user_a;

④ USER_A にログ記録権限を付与

GRANT INSERT ON audit_user.ddl_block_log TO user_a;

⑤ USER_Aでトリガーとテストテーブルを作成

CONNECT user_a/password

-- テスト用テーブル
CREATE TABLE emp (
empno NUMBER,
ename VARCHAR2(100)
);

🧠 DDLトリガー(DROP操作のブロック+ログ記録)

CREATE OR REPLACE TRIGGER trg_block_ddl
AFTER DROP ON SCHEMA
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO audit_user.ddl_block_log
VALUES (ora_dict_obj_name, ora_sysevent, SYSDATE);

COMMIT;

RAISE_APPLICATION_ERROR(-20005, 'このオブジェクトのDROPは禁止されています。');
END;
/

🔎 ポイント解説

記述説明
PRAGMA AUTONOMOUS_TRANSACTIONトリガー内で独立したトランザクションを開始
INSERTaudit_user.ddl_block_log にDROP操作の詳細を記録
COMMIT自律トランザクション内の変更を即時反映
RAISE_APPLICATION_ERRORDROP操作をユーザー定義エラーで停止

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

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


✅ 動作確認

DROP TABLE emp;

出力されるエラー(DROPはブロックされる):

ORA-20005: このオブジェクトのDROPは禁止されています。

🔍 ログ確認(AUDIT_USERで)

CONNECT audit_user/password

SELECT * FROM ddl_block_log;
OBJ_NAMEEVENTLOG_TIME
EMPDROP2025/06/29 01:45:00
SQL> CREATE USER audit_user IDENTIFIED BY password
2 DEFAULT TABLESPACE users
3 TEMPORARY TABLESPACE temp
4 QUOTA UNLIMITED ON users;

ユーザーが作成されました。

SQL> GRANT CONNECT, RESOURCE TO audit_user;

権限付与が成功しました。

SQL> CONNECT audit_user/password
接続されました。
SQL> CREATE TABLE ddl_block_log (
2 obj_name VARCHAR2(100),
3 event VARCHAR2(20),
4 log_time DATE
5 );

表が作成されました。

SQL> CONNECT / as sysdba
接続されました。
SQL> CREATE USER user_a IDENTIFIED BY password
2 DEFAULT TABLESPACE users
3 TEMPORARY TABLESPACE temp
4 QUOTA UNLIMITED ON users;

ユーザーが作成されました。

SQL> GRANT CONNECT, RESOURCE TO user_a;

権限付与が成功しました。

SQL> GRANT INSERT ON audit_user.ddl_block_log TO user_a;

権限付与が成功しました。

SQL> CONNECT user_a/password
接続されました。
SQL> CREATE TABLE emp (
2 empno NUMBER,
3 ename VARCHAR2(100)
4 );

表が作成されました。

SQL> CREATE OR REPLACE TRIGGER trg_block_ddl
2 AFTER DROP ON SCHEMA
3 DECLARE
4 PRAGMA AUTONOMOUS_TRANSACTION;
5 BEGIN
6 INSERT INTO audit_user.ddl_block_log
7 VALUES (ora_dict_obj_name, ora_sysevent, SYSDATE);

8 COMMIT;
9
10 RAISE_APPLICATION_ERROR(-20005, 'このオブジェクトのDROPは禁止されています。');
11
12 END;
13 /

トリガーが作成されました。

SQL> DROP TABLE emp;
DROP TABLE emp
*
行1でエラーが発生しました。:
ORA-04088: トリガー'USER_A.TRG_BLOCK_DDL'の実行中にエラーが発生しました ORA-00604:
再帰SQLレベル1でエラーが発生しました。 ORA-20005:
このオブジェクトのDROPは禁止されています。 ORA-06512: 行9



SQL> CONNECT audit_user/password
接続されました。
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY MM DD HH24:MI:SS';

セッションが変更されました。

SQL> set lin 1000
SQL> col obj_name for a20
SQL> col event for a20
SQL> SELECT * FROM ddl_block_log;

OBJ_NAME EVENT LOG_TIME
-------------------- -------------------- -------------------
EMP DROP 2025 06 29 15:25:29

🧩まとめ

項目内容
DROPの防止RAISE_APPLICATION_ERRORで確実に停止
ログの記録先別スキーマのテーブル audit_user.ddl_block_log
安全な構成に必要な工夫PRAGMA AUTONOMOUS_TRANSACTIONの利用
権限設定INSERT権限を user_a に付与


[参考]
14.12 CREATE TRIGGER文

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

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

コメント

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