読者です 読者をやめる 読者になる 読者になる

WHEN NO_DATA_FOUND THEN

Oracle Databaseについてつらつらと。。。

DROP/TRUNCATE TABLEを防ぐ方法

本番データの誤削除したというトラブルがあったようです。このトラブルのように全面削除というのはなかなか聞きませんが、1テーブルのレベルなら伝聞含め聞いたことは多いことかと思います。Oracle Databaseを使っている場合、どうすればこのようなトラブルの発生を防げるかを考えてみたいと思います。

まずはオプション製品を活用する方法です。Enterprise EditionのDatabase Vaultという、標準機能より高度な権限コントロールを行うオプションを導入して、取り決めた管理者の許可がある場合にのみDROP/TRUNCATE TABLEを実施できるように設定します。あるいはDROP/TRUNCATE TABLEを行うためのユーザーを別途作成し、データの操作を行うユーザーではDROP/TRUNCATE TABLEを実施できないように設定します。Database Valutの権限管理機能はかなり柔軟ですので、ほかの重要な操作含め、どのような設計を行うかが肝要です。

次に、オプション製品に頼らない方法です。SE/SE1でもできます。DROP/TRUNCATE TABLE文実行前に起動するトリガーを作成し、そのトリガーの中身を、絶対に例外が発生するようにコーディングします。たとえば以下のようなコーディングにすると、SCOTTスキーマのテーブルをDROPしようとしても常にORA-20001が発生するようになります。実際にはORA-00604も一緒に発生しますが。IF文をやめてRAISE_APPLICATION_ERRORプロシージャの呼び出しだけにすれば、テーブルを含めたすべてのオブジェクトのドロップが対象になります。

CREATE OR REPLACE TRIGGER cancel_drop_table
  BEFORE DROP ON scott.SCHEMA
BEGIN
  IF ora_dict_obj_type = 'TABLE' THEN
    RAISE_APPLICATION_ERROR(-20001, 'Never Drop!!');
  END IF;
END;

実際にテーブルをDROPしたい場合は、先にトリガーをDROPするか、DISABLEにする必要があります。トリガーを別のユーザーで作成して、テーブルのオーナーにそのトリガーのDROP権限がない状態にすれば尚いいですね。