ヘッダーをスキップ
Oracle® Database 2日で開発者ガイド
12c リリース1 (12.1)
B71350-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

6 トリガーの使用

この章の内容は、次のとおりです。

トリガーについて

トリガーはデータベースに格納され、(有効な状態の場合)指定されたイベントに対して自動的に実行される(起動する)PL/SQLユニットです。

トリガーは次のような構造です。

TRIGGER trigger_name
  triggering_event
  [ trigger_restriction ]
BEGIN
  triggered_action;
END;

trigger_nameは、スキーマ内のトリガーで一意である必要があります。トリガーには、スキーマ内の別の種類のオブジェクト(表など)と同じ名前を指定できますが、混乱を防ぐネーミング規則を使用することをお薦めします。

トリガーが有効な状態の場合、trigger_restrictionTRUEまたは省略されると、triggering_eventによりデータベースはtriggered_actionを実行します。triggering_eventは、表、ビュー、スキーマ、またはデータベースのいずれかに関連付けられており、次のうちのいずれかとなります。

トリガーが無効の状態のとき、triggering_eventはデータベースにtriggered_actionを実行させません。これは、trigger_restrictionTRUEの場合や省略された場合も同様です。

デフォルトでは、トリガーは有効な状態で作成されます。有効なトリガーを無効化したり、無効なトリガーを有効化することができます。

サブプログラムとは異なり、トリガーを直接起動することはできません。トリガーは、ユーザーまたはアプリケーションによって生じるトリガー・イベントによってのみ起動します。正常に処理されないエラーが発生しないかぎり、トリガーが実行されていることに気づかない可能性があります。

単純なトリガーは、次のいずれかのタイミング・ポイントで起動できます。

  • トリガー・イベントが実行される前(文レベルのBEFOREトリガー)

  • トリガー・イベントが実行された後(文レベルのAFTERトリガー)

  • イベントが影響する各行の前(行レベルのBEFOREトリガー)

  • イベントが影響する各行の後(行レベルのAFTERトリガー)

複合トリガーは複数のタイミング・ポイントで起動できます。複合トリガーの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

INSTEAD OFトリガーはビューで定義され、トリガー・イベントはDML文です。DML文を実行するかわりに、Oracle DatabaseはINSTEAD OFトリガーを実行します。詳細は、「INSTEAD OFトリガーの作成」を参照してください。

システム・トリガーは、スキーマまたはデータベースで定義されます。スキーマで定義されたトリガーは、スキーマの所有者(現在のユーザー)に関連付けられた各イベントに対して起動します。データベースで定義されたトリガーは、すべてのユーザーに関連付けられた各イベントに対して起動します。

トリガーの1つの使用目的は、すべてのクライアント・アプリケーションに適用されるビジネス・ルールを実行することです。たとえば、EMPLOYEES表に追加するデータが特定のフォーマットをもっていなければならず、多くのクライアント・アプリケーションがこの表にデータを追加できるとします。表のトリガーを使用すると、追加するすべてのデータが適切なフォーマットになります。任意のクライアントが表にデータを追加するたびにトリガーが実行されるため、クライアントはルールを回避することができず、ルールを実行するコードは、すべてのクライアント・アプリケーションではなくトリガーにのみ格納されて保持されます。トリガーの他の使用目的の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。


参照:

トリガーの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

トリガーの作成

トリガーを作成するには、SQL Developerのトリガーの作成ツールまたはDDL文のCREATE TRIGGERを使用します。ここでは、これらの方法を使用してトリガーを作成する方法について説明します。

デフォルトでは、トリガーは有効な状態で作成されます。無効な状態でトリガーを作成するには、DISABLE句のあるCREATE TRIGGER文を使用します。


注意:

トリガーを作成するには、適切な権限を所持する必要がありますが、ここでの説明では、この追加情報は必要ありません。

この項の内容は次のとおりです。


注意:

このマニュアルのチュートリアルを行うには、ユーザーHRとして、SQL DeveloperからOracle Databaseに接続している必要があります。


参照:


OLDおよびNEW疑似レコードについて

行レベルのトリガーが起動すると、PL/SQLランタイム・システムは2つの疑似レコードOLDおよびNEWを作成および移入します。レコードのプロパティのすべてではなく、一部を持つため、疑似レコードと呼ばれます。

トリガーが処理している行では、次のようになります。

  • INSERTトリガーの場合、OLDには値が含まれず、NEWには新しい値が含まれます。

  • UPDATEトリガーの場合、OLDには古い値が含まれ、NEWには新しい値が含まれます。

  • DELETEトリガーの場合、OLDには古い値が含まれ、NEWには値が含まれません。

疑似レコードを参照するには、例6-1のように、:OLDまたは:NEWと名前の前にコロンを付けます。


参照:

OLDおよびNEW疑似レコードの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

チュートリアル: 表の変更を記録するトリガーの作成

このチュートリアルでは、CREATE TRIGGER文を使用してEVAL_CHANGE_TRIGGERトリガーを作成する方法を示します。このトリガーは、INSERTUPDATEまたはDELETE文によってEVALUATIONS表が変更されるたびにEVALUATIONS_LOG表に行を追加します。

このトリガーは、トリガー文が実行された後に行を追加し、条件述語INSERTINGUPDATINGおよびDELETINGを使用して、使用可能な3つのDML文のうち、トリガーを起動した文を判断します。

EVAL_CHANGE_TRIGGERは、文レベルのトリガーで、AFTERトリガーです。

EVALUATIONS_LOGおよびEVAL_CHANGE_TRIGGERを作成するには、次の手順を実行します。

  1. EVALUATIONS_LOG表を作成します。

    CREATE TABLE EVALUATIONS_LOG ( log_date DATE
                                 , action VARCHAR2(50));
    
  2. EVAL_CHANGE_TRIGGERを作成します。

    CREATE OR REPLACE TRIGGER EVAL_CHANGE_TRIGGER
      AFTER INSERT OR UPDATE OR DELETE
      ON EVALUATIONS
    DECLARE
      log_action  EVALUATIONS_LOG.action%TYPE;
    BEGIN
      IF INSERTING THEN
        log_action := 'Insert';
      ELSIF UPDATING THEN
        log_action := 'Update';
      ELSIF DELETING THEN
        log_action := 'Delete';
      ELSE
        DBMS_OUTPUT.PUT_LINE('This code is not reachable.');
      END IF;
    
      INSERT INTO EVALUATIONS_LOG (log_date, action)
        VALUES (SYSDATE, log_action);
    END;
    

参照:

条件述部の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

チュートリアル: 行を挿入する前に行に対して主キーを生成するトリガーの作成

(「チュートリアル: 順序の作成」で作成した)順序EVALUATIONS_SEQUENCEは、(「表の作成」で作成した)EVALUATIONS表の主キーを生成します。ただし、これらの主キーは自動的に表に挿入されません。

このチュートリアルでは、SQL Developerのトリガーの作成ツールを使用して、NEW_EVALUATION_TRIGGERというトリガーを作成する方法を説明します。このトリガーはEVALUATIONS表に行が挿入されるに起動し、EVALUATIONS_SEQUENCEを使用して、その行の主キーに対する一意の番号を生成します。INSERT文のトリガーの影響を受ける行ごとに、このトリガーは一度起動します。

NEW_EVALUATION_TRIGGERは、行レベルのトリガーで、BEFOREトリガーです。

NEW_EVALUATIONトリガーを作成するには、次の手順を実行します。

  1. 「接続」フレームで、hr_connを展開します。

  2. スキーマ・オブジェクト・タイプのリストで、「トリガー」を右クリックします。

  3. 選択肢のリストで、「新規トリガー」をクリックします。

  4. 「トリガーの作成」ウィンドウで、次の手順を実行します。

    1. 「名前」フィールドで、NEW_EVALUATION_TRIGGERと入力してデフォルト値TRIGGER1を上書きします。

    2. ベース・オブジェクトでは、メニューからEVALUATIONSを選択します。

    3. INSERTを「使用可能なイベント」から「選択済のイベント」に移動します。

      (INSERTを選択して「>」をクリックします。)

    4. 「文レベル」オプションを選択解除します。

    5. 「OK」をクリックします。

      NEW_EVALUATION_TRIGGERペインが開き、トリガーを作成したCREATE TRIGGER文が表示されます。

      CREATE OR REPLACE
      TRIGGER NEW_EVALUATION_TRIGGER
      BEFORE INSERT ON EVALUATIONS
      FOR EACH ROW
      BEGIN
        NULL;
      END;
      

      NEW_EVALUATION_TRIGGERペインのタイトルがイタリック・フォントになっています。これは、トリガーがまだデータベースに保存されていないことを示しています。

  5. CREATE TRIGGER文で、NULLを次と置き換えます。

    :NEW.evaluation_id := evaluations_sequence.NEXTVAL
    
  6. 「ファイル」メニューから、「保存」を選択します。

    Oracle Databaseは、プロシージャをコンパイルして保存します。NEW_EVALUATION_TRIGGERペインのタイトルがイタリック・フォントではなくなります。

INSTEAD OFトリガーの作成

ビューは、問合せの出力を表形式で表します。表の変更と同時にビューも変更する場合、INSTEAD OFトリガーを作成する必要があります。このトリガーは、ビューを変更するかわりに基礎となる表を変更します。

たとえば、EMP_LOCATIONSというビューを検討します。 NAME列は、EMPLOYEES表のLAST_NAMEおよびFIRST_NAME列から作成されています。

CREATE VIEW EMP_LOCATIONS AS
SELECT e.EMPLOYEE_ID,
  e.LAST_NAME || ', ' || e.FIRST_NAME NAME,
  d.DEPARTMENT_NAME DEPARTMENT,
  l.CITY CITY,
  c.COUNTRY_NAME COUNTRY
FROM EMPLOYEES e, DEPARTMENTS d, LOCATIONS l, COUNTRIES c
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID AND
 d.LOCATION_ID = l.LOCATION_ID AND
 l.COUNTRY_ID = c.COUNTRY_ID
ORDER BY LAST_NAME;

ビューEMP_LOCATIONS.NAME(「CREATE VIEW文によるビューの作成」で作成)を更新するには、EMPLOYEES.LAST_NAMEおよびEMPLOYEES.FIRST_NAMEを更新する必要があります。これは、例6-1INSTEAD OFトリガーによって実行されます。

OLDNEW擬似レコードです。行レベルのトリガーが起動したときにPL/SQL実行時エンジンによって作成され、それぞれ値を入れられます。 OLDおよびNEWは、トリガーによって処理されているレコードの元の値と新しい値をそれぞれ格納します。PL/SQLレコードの一部のプロパティを持たないため、疑似レコードと呼ばれます。

例6-1 INSTEAD OFトリガーの作成

CREATE OR REPLACE TRIGGER update_name_view_trigger
INSTEAD OF UPDATE ON emp_locations
BEGIN
  UPDATE employees SET
    first_name = substr( :NEW.name, instr( :new.name, ',' )+2),
    last_name = substr( :NEW.name, 1, instr( :new.name, ',')-1)
  WHERE employee_id = :OLD.employee_id;
END;

参照:

  • INSTEAD OFトリガーの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

  • OLDおよびNEWの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。


チュートリアル: LOGONおよびLOGOFFイベントを記録するトリガーの作成

このチュートリアルでは、CREATE TRIGGER文を使用して、HR_LOGON_TRIGGERHR_LOGOFF_TRIGGERの2つのトリガーを作成する方法を説明します。ユーザーHRとしてログオンしたHR_LOGON_TRIGGERHR_USERS_LOG表に行を追加します。ユーザーHRとしてログオフするに、HR_LOGOFF_TRIGGERHR_USERS_LOG表に行を追加します。

HR_LOGON_TRIGGERおよびHR_LOGOFF_TRIGGERシステム・トリガーです。HR_LOGON_TRIGGERAFTERトリガーHR_LOGOFF_TRIGGERBEFOREトリガーです。

HR_USERS_LOG、HR_LOGON_TRIGGERおよびHR_LOGOFF_TRIGGERを作成するには、次の手順を実行します。

  1. HR_USERS_LOG表を作成します。

    CREATE TABLE hr_users_log (
      user_name VARCHAR2(30),
      activity VARCHAR2(20),
      event_date DATE
    );
    
  2. hr_logon_triggerを作成します。

    CREATE OR REPLACE TRIGGER hr_logon_trigger
      AFTER LOGON
      ON HR.SCHEMA
    BEGIN
      INSERT INTO hr_users_log (user_name, activity, event_date)
      VALUES (USER, 'LOGON', SYSDATE);
    END;
    
  3. hr_logoff_triggerを作成します。

    CREATE OR REPLACE TRIGGER hr_logoff_trigger
      BEFORE LOGOFF
      ON HR.SCHEMA
    BEGIN
      INSERT INTO hr_users_log (user_name, activity, event_date)
      VALUES (USER, 'LOGOFF', SYSDATE);
    END;
    

参照:

システム・トリガーの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

トリガーの変更

トリガーを変更するには、SQL Developerの編集ツールを使用するか、OR REPLACE句を指定してCREATE TRIGGER DDL文を使用します。

編集ツールを使用してトリガーを変更するには、次の手順を実行します。

  1. 「接続」フレームで、hr_connを展開します。

  2. スキーマ・オブジェクト・タイプのリストで、「トリガー」を展開します。

  3. トリガーのリストで、変更するトリガーをクリックします。

  4. 「接続」フレームの右側の「コード」ペインに、トリガーを作成したコードが表示されます。

    「コード」ペインが書込みモードになっています。(鉛筆アイコンをクリックすると、モードが書込みモードから読取り専用モードに、またはその逆に切り替わります。)

  5. 「コード」ペインで、コードを変更します。

    ペインのタイトルはイタリック・フォントになっており、変更がデータベースに保存されていないことを示しています。

  6. 「ファイル」メニューから、「保存」を選択します。

    Oracle Databaseは、トリガーをコンパイルして保存します。ペインのタイトルがイタリック・フォントではなくなります。


参照:

  • CREATE OR REPLACE TRIGGER文に適用される一般情報は、「データ定義言語(DDL)文について」を参照してください。

  • CREATE OR REPLACE TRIGGER文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。


トリガーの無効化および有効化

トリガーが使用不可能なオブジェクトを参照している場合、またはトリガーが原因である遅延なしに大規模なデータのアップロードを実行する必要がある場合(リカバリ操作など)、トリガーを一時的に無効にする必要があります。参照されたオブジェクトが使用可能になった後、またはデータのアップロード終了後に、トリガーを再度有効にすることができます。

この項の内容は次のとおりです。


参照:

  • ALTER TRIGGER文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

  • ALTER TABLE文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。


単一のトリガーの無効化または有効化

単一のトリガーを無効化または有効化するには、トリガーの無効化/トリガーの有効化ツール、あるいはDISABLEまたはENABLE句を指定してALTER TRIGGER文を使用します。

たとえば、次の文ではeval_change_triggerを無効化および有効化します。

ALTER TRIGGER eval_change_trigger DISABLE;
ALTER TRIGGER eval_change_trigger ENABLE;

トリガーの無効化/トリガーの有効化ツールを使用するには、次の手順を実行します。

  1. 「接続」フレームで、hr_connを展開します。

  2. スキーマ・オブジェクト・タイプのリストで、「トリガー」を展開します。

  3. トリガーのリストで、対象のトリガーを右クリックします。

  4. 選択肢のリストで、「無効化」または「有効化」を選択します。

  5. 「無効化」または「有効化」ウィンドウで、「適用」をクリックします。

  6. 「確認」ウィンドウで「OK」をクリックします。

単一の表のすべてのトリガーの無効化または有効化

特定の表のすべてのトリガーを無効化または有効化するには、すべてのトリガーの無効化/すべてのトリガーの有効化ツール、あるいはDISABLE ALL TRIGGERSまたはENABLE ALL TRIGGERS句を指定してALTER TABLE文を使用します。

たとえば、次の文ではevaluations表のすべてのトリガーを無効化および有効化します。

ALTER TABLE evaluations DISABLE ALL TRIGGERS;
ALTER TABLE evaluations ENABLE ALL TRIGGERS;

すべてのトリガーの無効化/すべてのトリガーの有効化ツールを使用するには、次の手順を実行します。

  1. 「接続」フレームで、hr_connを展開します。

  2. スキーマ・オブジェクト・タイプのリストで、「表」を展開します。

  3. 表のリストで、対象の表を右クリックします。

  4. 選択肢のリストで、「トリガー」を選択します。

  5. 選択肢のリストで、「すべて無効化」または「すべて有効化」を選択します。

  6. 「すべて無効化」または「すべて有効化」ウィンドウで、「適用」をクリックします。

  7. 「確認」ウィンドウで「OK」をクリックします。

トリガーのコンパイルおよび依存性について

CREATE TRIGGER文を実行すると、作成中のトリガーがコンパイルされます。このコンパイルでエラーが発生した場合、CREATE TRIGGER文は失敗します。コンパイル・エラーを表示するには、このビューを使用します。

SELECT * FROM USER_ERRORS WHERE TYPE = 'TRIGGER';

コンパイルされたトリガーは、トリガーが定義されたスキーマ・オブジェクトに依存します。たとえば、NEW_EVALUATION_TRIGGEREVALUATIONS表に依存します。

CREATE OR REPLACE
TRIGGER NEW_EVALUATION_TRIGGER
BEFORE INSERT ON EVALUATIONS
FOR EACH ROW
BEGIN
  :NEW.evaluation_id := evaluations_seq.NEXTVAL;
END;

トリガーが依存するスキーマ・オブジェクトを表示するには、次の文を使用します。

SELECT * FROM ALL_DEPENDENCIES WHERE TYPE = 'TRIGGER';

トリガーが依存するオブジェクトが削除された場合、またはトリガーとオブジェクトが一致しないような変更が行われた場合、トリガーは無効化されます。トリガーは、次の起動時に再コンパイルされます。トリガーをすぐに再コンパイルするには、COMPILE句を含むALTER TRIGGER文を使用します。次に例を示します。

ALTER TRIGGER NEW_EVALUATION_TRIGGER COMPILE;

参照:

トリガーのコンパイルおよび依存性の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

トリガーの削除

トリガーが依存するオブジェクトを削除する前に、トリガーを削除する必要があります。

トリガーを削除するには、SQL Developerの「接続」フレームと削除ツールまたはDDL文のDROP TRIGGERを使用します。

この文は、トリガーEVAL_CHANGE_TRIGGERを削除します。

DROP TRIGGER EVAL_CHANGE_TRIGGER;

削除ツールを使用してトリガーを削除するには、次の手順を実行します。

  1. 「接続」フレームで、hr_connを展開します。

  2. スキーマ・オブジェクト・タイプのリストで、「トリガー」を展開します。

  3. トリガーのリストで、削除するトリガーの名前を右クリックします。

  4. 選択肢のリストで、「トリガーの削除」をクリックします。

  5. 削除ウィンドウで、「適用」をクリックします。

  6. 「確認」ウィンドウで「OK」をクリックします。


参照:

  • DROP TRIGGER文に適用される一般情報は、「データ定義言語(DDL)文について」を参照してください。

  • DROP TRIGGER文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。