この章の内容は次のとおりです。
トリガーはデータベースに格納され、(有効な状態の場合)指定されたイベントに対して自動的に実行される(起動する)PL/SQLユニットです。
トリガーは次のような構造です。
TRIGGER trigger_name triggering_event [ trigger_restriction ] BEGIN triggered_action; END;
trigger_name
は、スキーマ内のトリガーで一意である必要があります。トリガーには、スキーマ内の別の種類のオブジェクト(表など)と同じ名前を指定できますが、混乱を防ぐネーミング規則を使用することをお薦めします。
トリガーが有効な状態の場合、trigger_restriction
がTRUE
または省略されると、triggering_event
によりデータベースはtriggered_action
を実行します。triggering_event
は、表、ビュー、スキーマ、またはデータベースのいずれかに関連付けられており、次のうちのいずれかとなります。
DML文(「データ操作言語(DML)文について」を参照)
DDL文(「データ定義言語(DDL)文について」を参照)
データベース処理(SERVERERROR
、LOGON
、LOGOFF
、STARTUP
またはSHUTDOWN
)
トリガーが無効の状態のとき、triggering_event
はデータベースにtriggered_action
を実行させません。これは、trigger_restriction
がTRUE
の場合や省略された場合も同様です。
デフォルトでは、トリガーは有効な状態で作成されます。有効なトリガーを無効化したり、無効なトリガーを有効化することができます。
サブプログラムとは異なり、トリガーを直接起動することはできません。トリガーは、ユーザーまたはアプリケーションによって生じるトリガー・イベントによってのみ起動します。正常に処理されないエラーが発生しないかぎり、トリガーが実行されていることに気づかない可能性があります。
単純なトリガーは、次のいずれかのタイミング・ポイントで起動できます。
イベントが影響する各行の後(行レベルの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 Express Edition (Oracle Database XE)に接続している必要があります。 |
参照:
|
行レベルのトリガーが起動すると、PL/SQLランタイム・システムは2つの疑似レコードOLD
およびNEW
を作成および移入します。レコードのプロパティのすべてではなく、一部を持つため、疑似レコードと呼ばれます。
トリガーが処理している行では、次のようになります。
INSERT
トリガーの場合、OLD
には値が含まれず、NEW
には新しい値が含まれます。
UPDATE
トリガーの場合、OLD
には古い値が含まれ、NEW
には新しい値が含まれます。
DELETE
トリガーの場合、OLD
には古い値が含まれ、NEW
には値が含まれません。
疑似レコードを参照するには、例8-1のように、:OLD
または:NEW
と名前の前にコロンを付けます。
参照: OLD およびNEW 疑似レコードの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 |
このチュートリアルでは、CREATE
TRIGGER
文を使用してEVAL_CHANGE_TRIGGER
トリガーを作成する方法を示します。このトリガーは、INSERT
、UPDATE
またはDELETE
文によってEVALUATIONS
表が変更されるたびにEVALUATIONS_LOG
表に行を追加します。
このトリガーは、トリガー文が実行された後に行を追加し、条件述語INSERTING
、UPDATING
およびDELETING
を使用して、使用可能な3つのDML文のうち、トリガーを起動した文を判断します。
EVAL_CHANGE_TRIGGER
は、文レベルのトリガーで、AFTERトリガーです。
このトリガーは、このマニュアルのチュートリアルと例で、開発とデプロイの方法を説明するためのサンプル・アプリケーションの一部です。
EVALUATIONS_LOGおよびEVAL_CHANGE_TRIGGERを作成するには、次の手順を実行します。
EVALUATIONS_LOG
表を作成します。
CREATE TABLE EVALUATIONS_LOG ( log_date DATE , action VARCHAR2(50));
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;
順序EVALUATIONS_SEQ
は、EVALUATIONS
表の主キーを作成します。ただし、これらの主キーは自動的に表に挿入されません。
このチュートリアルでは、SQL Developerのトリガーの作成ツールを使用して、NEW_EVALUATION_TRIGGER
というトリガーを作成する方法を説明します。このトリガーはEVALUATIONS
表に行が挿入される前に起動し、evaluations_seq
を使用して、その行の主キーに対する一意の番号を生成します。INSERT
文のトリガーの影響を受ける行ごとに、このトリガーは一度起動します。
NEW_EVALUATION_TRIGGER
は、行レベルのトリガーで、BEFOREトリガーです。
このトリガーは、このマニュアルのチュートリアルと例で、開発とデプロイの方法を説明するためのサンプル・アプリケーションの一部です。
NEW_EVALUATIONトリガーを作成するには、次の手順を実行します。
「接続」タブで、hr_connを展開します。
hr_conn
アイコンの下に、スキーマ・オブジェクト型のリストが表示されます。
「トリガー」を右クリックします。
選択肢のリストが表示されます。
「新規トリガー」をクリックします。
「トリガーの作成」ウィンドウが開きます。「スキーマ」フィールドにはHR
という値が、名前フィールドにはデフォルト値のTRIGGER1
があります。
「名前」フィールドにNEW_EVALUATION_TRIGGER
と入力し、デフォルト値を上書きします。
「トリガー」タブをクリックします。
トリガーペインが表示されます。デフォルトでは、「トリガー・タイプ」フィールドの値はTABLE
で、「有効」チェック・ボックスが選択され、「表所有者」の値はHR
、「表名」フィールドは空で、前および文レベル・オプションが選択され、後および行レベル・オプションの選択が解除され、「挿入」、「更新」、および「削除」チェック・ボックスの選択が解除されています。
「表名」フィールドのメニューから、EVALUATIONS
を選択します。
「行レベル」オプションを選択します。
「文レベル」オプションの選択が解除されます。
「挿入」チェック・ボックスを選択します。
「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
ペインのタイトルがイタリック・フォントになっています。これは、トリガーがまだデータベースに保存されていないことを示しています。
CREATE
TRIGGER
文で、NULL
を次と置き換えます。
:NEW.evaluation_id := evaluations_seq.NEXTVAL
「ファイル」メニューから、「保存」を選択します。
Oracle Database XEは、プロシージャをコンパイルして保存します。NEW_EVALUATION_TRIGGER
ペインのタイトルがイタリック・フォントではなくなります。
ビューは、問合せの出力を表形式で表します。表を変更するのと同様にビューを変更する場合は、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
を更新するには、EMPLOYEES
.LAST_NAME
およびEMPLOYEES
.FIRST_NAME
を更新する必要があります。これは、例8-1のINSTEAD
OF
トリガーによって実行されます。
このトリガーは、このマニュアルのチュートリアルと例で、開発とデプロイの方法を説明するためのサンプル・アプリケーションの一部です。
NEW
およびOLD
は、行レベルのトリガーが起動するたびにPL/SQLランタイム・エンジンが作成および移入する疑似レコードです。 OLD
およびNEW
は、トリガーによって処理されているレコードの元の値と新しい値をそれぞれ格納します。PL/SQLレコードの一部のプロパティを持たないため、疑似レコードと呼ばれます。
例8-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;
参照: 『Oracle Database PL/SQL言語リファレンス』 |
このチュートリアルでは、CREATE
TRIGGER
文を使用してhr_logon_trigger
およびhr_logoff_trigger
の2つのトリガーを作成する方法を示します。hr_logon_trigger
は、ユーザーHR
としてログオンした後にHR_USERS_LOG
表に行を追加します。hr_logoff_trigger
は、ユーザーHR
としてログオフする前に、HR_USERS_LOG
表に行を追加します。
hr_logon_trigger
およびhr_logoff_trigger
は、システム・トリガーです。 hr_logon_trigger
はBEFOREトリガーであり、hr_logoff_trigger
はAFTERトリガーです。
これらのトリガーは、このマニュアルのチュートリアルと例で、開発とデプロイの方法を説明するためのサンプル・アプリケーションの一部ではありません。
HR_USERS_LOG、HR_LOGON_TRIGGERおよびHR_LOGOFF_TRIGGERを作成するには、次の手順を実行します。
HR_USERS_LOG
表を作成します。
CREATE TABLE hr_users_log ( user_name VARCHAR2(30), activity VARCHAR2(20), event_date DATE );
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;
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;
トリガーを変更するには、SQL Developerの編集ツールを使用するか、OR
REPLACE
句を指定してCREATE
TRIGGER
DDL文を使用します。
「編集」ツールを使用してトリガーを変更するには、次の手順を実行します。
「接続」タブで、hr_connを展開します。
hr_conn
アイコンの下に、スキーマ・オブジェクト型のリストが表示されます。
「トリガー」を展開します。
トリガーのリストが表示されます。
変更するトリガーをクリックします。
「接続」ペインの右側に、フレームが表示されます。上部のタブには変更するトリガーの名前が表示されます。その下にあるのはサブタブです。
「コード」サブタブをクリックします。
「コード」ペインが表示され、トリガーを作成したコードが表示されます。「コード」ペインが書込みモードになっています。(鉛筆アイコンをクリックすると、モードが書込みモードから読取り専用モードに、またはその逆に切り替わります。)
「コード」ペインで、コードを変更します。
ペインのタイトルはイタリック・フォントになっており、変更がデータベースに保存されていないことを示しています。
「ファイル」メニューから、「保存」を選択します。
Oracle Database XEは、トリガーをコンパイルして保存します。ペインのタイトルがイタリック・フォントではなくなります。
参照:
|
トリガーが使用不可能なオブジェクトを参照している場合、またはトリガーが原因である遅延なしに大規模なデータのアップロードを実行する必要がある場合(リカバリ操作など)、トリガーを一時的に無効にする必要があります。参照されたオブジェクトが使用可能になった後、またはデータのアップロード終了後に、トリガーを再度有効にすることができます。
単一のトリガーを無効化または有効化するには、DISABLE
またはENABLE
句を指定してALTER
TRIGGER
文を使用します。次に例を示します。
ALTER TRIGGER eval_change_trigger DISABLE; ALTER TRIGGER eval_change_trigger ENABLE;
特定の表のすべてのトリガーを無効化または有効化するには、DISABLE
ALL
TRIGGERS
またはENABLE
ALL
TRIGGERS
句を指定してALTER
TABLE
文を使用します。次に例を示します。
ALTER TABLE evaluations DISABLE ALL TRIGGERS; ALTER TABLE evaluations ENABLE ALL TRIGGERS;
参照:
|
CREATE
TRIGGER
文を実行すると、作成中のトリガーがコンパイルされます。トリガーのコンパイルによってエラーが生じた場合、CREATE
TRIGGER
文は失敗します。コンパイル・エラーを表示するには、次の文を実行します。
SELECT * FROM USER_ERRORS WHERE TYPE = 'TRIGGER';
コンパイルされたトリガーは、トリガーが定義されたスキーマ・オブジェクトに依存します。たとえば、NEW_EVALUATION_TRIGGER
はEVALUATIONS
表に依存します。
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;
参照:
|
トリガーが依存するオブジェクトを削除する前に、トリガーを削除する必要があります。
トリガーを削除するには、SQL Developerのナビゲーション・フレームと削除ツールまたはDDL文のDROP
TRIGGER
を使用します。
削除ツールを使用してトリガーを削除するには、次の手順を実行します。
「接続」タブで、hr_connを展開します。
hr_conn
アイコンの下に、スキーマ・オブジェクト型のリストが表示されます。
「トリガー」を展開します。
トリガーのリストが表示されます。
削除するトリガーの名前を右クリックします。
選択肢のリストが表示されます。
「トリガーの削除」をクリックします。
「削除」ウィンドウが開きます。
「適用」をクリックします。
「確認」ウィンドウが開きます。
「OK」をクリックします。
参照:
|