6 トリガーの使用
トリガーは、指定されたイベントに対応して自動的に実行するストアドPL/SQLユニットです。
- トリガーについて
トリガーはデータベースに格納され、(有効な状態の場合)指定されたイベントに対して自動的に実行される(起動する)PL/SQLユニットです。 - トリガーの作成
トリガーを作成するには、SQL Developerのグラフィカル・インタフェースまたはDDL文CREATE TRIGGERのいずれかを使用します。 - トリガーの変更
トリガーを変更するには、SQL Developerの編集ツールを使用するか、OR REPLACE句を指定してDDL文CREATE TRIGGERを使用します。 - トリガーの無効化および有効化
使用不可能なオブジェクトを参照するトリガーや、トリガーが原因の遅延なしに大量のデータをアップロードする(リカバリ操作など)トリガーを一時的に無効にする必要があります。参照されたオブジェクトが使用可能になった後、またはデータのアップロード終了後に、トリガーを再度有効にすることができます。 - トリガーのコンパイルおよび依存性について
コンパイルされたトリガーは、それらが定義されているスキーマ・オブジェクトに依存します。トリガーが依存するオブジェクトが削除または変更され、トリガーとオブジェクトの不一致が生じた場合、そのトリガーは無効になります。 - トリガーの削除
6.1 トリガーについて
トリガーはデータベースに格納され、(有効な状態の場合)指定されたイベントに対して自動的に実行される(起動する)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の場合や省略された場合も同様です。
デフォルトでは、トリガーは有効な状態で作成されます。有効なトリガーを無効化したり、無効なトリガーを有効化することができます。
サブプログラムとは異なり、トリガーを直接起動することはできません。トリガーは、ユーザーまたはアプリケーションによって生じるトリガー・イベントによってのみ起動します。正常に処理されないエラーが発生しないかぎり、トリガーが実行されていることに気づかない可能性があります。
単純なトリガーは、次のいずれかのタイミング・ポイントで起動できます。
-
トリガー・イベントが実行される前(文レベルの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言語リファレンス』を参照してください。
親トピック: トリガーの使用
6.2 トリガーの作成
トリガーを作成するには、SQL Developerのグラフィカル・インタフェースまたはDDL文CREATE TRIGGERのいずれかを使用します。
ここでは、これらの方法を使用してトリガーを作成する方法について説明します。
デフォルトでは、トリガーは有効な状態で作成されます。無効な状態でトリガーを作成するには、DISABLE句のあるCREATE TRIGGER文を使用します。
注意:
トリガーを作成するには、適切な権限を所持する必要がありますが、ここでの説明では、この追加情報は必要ありません。
注意:
このマニュアルのチュートリアルを行うには、ユーザーHRとして、SQL DeveloperからOracle Databaseに接続している必要があります。
- OLDおよびNEW擬似レコードについて
行レベルのトリガーが起動すると、PL/SQL実行時システムによって、OLDおよびNEWという擬似レコードが作成され、それぞれ値を入れられます。レコードのプロパティのすべてではなく、一部を持つため、疑似レコードと呼ばれます。 - チュートリアル: 表の変更を記録するトリガーの作成
このチュートリアルでは、CREATE TRIGGER文を使用してEVAL_CHANGE_TRIGGERトリガーを作成する方法を示します。このトリガーは、INSERT、UPDATE、またはDELETE文によってEVALUATIONS表が変更されるたびにEVALUATIONS_LOG表に行を追加します。 - チュートリアル: 行を挿入する前に行に対して主キーを生成するトリガーの作成
このチュートリアルでは、SQL Developerのトリガーの作成ツールを使用して、EVALUATIONS表に行が挿入される前に起動し、EVALUATIONS_SEQUENCEを使用して、その行の主キーに対する一意の番号を生成するトリガーを作成する方法を説明します。 - INSTEAD OFトリガーの作成
ビューは、表として問合せ結果を表示します。表の変更と同時にビューも変更する場合、INSTEAD OFトリガーを作成する必要があります。このトリガーは、ビューを変更するかわりに基礎となる表を変更します。 - チュートリアル: LOGONおよびLOGOFFイベントを記録するトリガーの作成
このチュートリアルでは、CREATE TRIGGER文を使用して、HR_LOGON_TRIGGERとHR_LOGOFF_TRIGGERの2つのトリガーを作成する方法を説明します。ユーザーHRとしてログオンした後、HR_LOGON_TRIGGERはHR_USERS_LOG表に行を追加します。ユーザーHRとしてログオフする前に、HR_LOGOFF_TRIGGERはHR_USERS_LOG表に行を追加します。
関連項目:
-
CREATE TRIGGER文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
親トピック: トリガーの使用
6.2.1 OLDおよびNEW疑似レコードについて
行レベルのトリガーが起動すると、PL/SQLランタイム・システムは2つの疑似レコードOLDおよびNEWを作成および移入します。レコードのプロパティのすべてではなく、一部を持つため、疑似レコードと呼ばれます。
トリガーが処理している行では、次のようになります。
-
INSERTトリガーの場合、OLDには値が含まれず、NEWには新しい値が含まれます。
-
UPDATEトリガーの場合、OLDには古い値が含まれ、NEWには新しい値が含まれます。
-
DELETEトリガーの場合、OLDには古い値が含まれ、NEWには値が含まれません。
疑似レコードを参照するには、例6-1のように、:OLD
または:NEW
と名前の前にコロンを付けます。
6.2.2 チュートリアル: 表の変更を記録するトリガーの作成
このチュートリアルでは、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を作成するには、次の手順を実行します。
関連項目:
条件述部の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
親トピック: トリガーの作成
6.2.3 チュートリアル: 行を挿入する前に行に対して主キーを生成するトリガーの作成
このチュートリアルでは、SQL Developerのトリガーの作成ツールを使用して、EVALUATIONS表に行が挿入される前に起動し、EVALUATIONS_SEQUENCEを使用して、その行の主キーに対する一意の番号を生成するトリガーを作成する方法を説明します。
(「チュートリアル: 順序の作成」で作成した)順序EVALUATIONS_SEQUENCEは、(「表の作成」で作成した)EVALUATIONS表の主キーを生成します。ただし、これらの主キーは自動的に表に挿入されません。
このチュートリアルでは、SQL Developerのトリガーの作成ツールを使用して、NEW_EVALUATION_TRIGGERというトリガーを作成する方法を説明します。このトリガーはEVALUATIONS表に行が挿入される前に起動し、EVALUATIONS_SEQUENCEを使用して、その行の主キーに対する一意の番号を生成します。INSERT文のトリガーの影響を受ける行ごとに、このトリガーは一度起動します。
NEW_EVALUATION_TRIGGERは、行レベルのトリガーで、BEFOREトリガーです。
NEW_EVALUATIONトリガーを作成するには、次の手順を実行します。
-
「接続」フレームで、hr_connを展開します。
-
スキーマ・オブジェクト・タイプのリストで、「トリガー」を右クリックします。
-
選択肢のリストで、「新規トリガー」をクリックします。
-
「トリガーの作成」ウィンドウで、次の手順を実行します。
-
「名前」フィールドで、NEW_EVALUATION_TRIGGERと入力してデフォルト値TRIGGER1を上書きします。
-
ベース・オブジェクトでは、メニューからEVALUATIONSを選択します。
-
INSERTを「使用可能なイベント」から「選択済のイベント」に移動します。
(INSERTを選択して「>」をクリックします。)
-
「文レベル」オプションを選択解除します。
-
「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_sequence.NEXTVAL
-
「File」メニューから、「Save」を選択します。
Oracle Databaseは、プロシージャをコンパイルして保存します。NEW_EVALUATION_TRIGGERペインのタイトルがイタリック・フォントではなくなります。
親トピック: トリガーの作成
6.2.4 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-1のINSTEAD OFトリガーによって実行されます。
OLDとNEWは擬似レコードです。行レベルのトリガーが起動したときに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言語リファレンス』を参照してください。
親トピック: トリガーの作成
6.2.5 チュートリアル: LOGONおよびLOGOFFイベントを記録するトリガーの作成
このチュートリアルでは、CREATE TRIGGER文を使用して、HR_LOGON_TRIGGERとHR_LOGOFF_TRIGGERの2つのトリガーを作成する方法を説明します。ユーザーHRとしてログオンした後、HR_LOGON_TRIGGERはHR_USERS_LOG表に行を追加します。ユーザーHRとしてログオフする前に、HR_LOGOFF_TRIGGERはHR_USERS_LOG表に行を追加します。
HR_LOGON_TRIGGERおよびHR_LOGOFF_TRIGGERはシステム・トリガーです。HR_LOGON_TRIGGERはAFTERトリガー、HR_LOGOFF_TRIGGERはBEFOREトリガーです。
HR_USERS_LOG、HR_LOGON_TRIGGERおよびHR_LOGOFF_TRIGGERを作成するには、次の手順を実行します。
関連項目:
システム・トリガーの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
親トピック: トリガーの作成
6.3 トリガーの変更
トリガーを変更するには、SQL Developerの編集ツールを使用するか、OR REPLACE句を指定してCREATE TRIGGER DDL文を使用します。
編集ツールを使用してトリガーを変更するには、次の手順を実行します。
関連項目:
-
CREATE OR REPLACE TRIGGER文に適用される一般情報は、「データ定義言語(DDL)文について」を参照してください。
-
CREATE OR REPLACE TRIGGER文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
親トピック: トリガーの使用
6.4 トリガーの無効化および有効化
使用不可能なオブジェクトを参照するトリガーや、トリガーが原因の遅延なしに大量のデータをアップロードする(リカバリ操作など)トリガーを一時的に無効にする必要があります。参照されたオブジェクトが使用可能になった後、またはデータのアップロード終了後に、トリガーを再度有効にすることができます。
- 単一のトリガーの無効化または有効化
単一のトリガーを無効化または有効化するには、トリガーの無効化/トリガーの有効化ツール、あるいはDISABLEまたはENABLE句を指定してALTER TRIGGER文を使用します。 - 単一の表のすべてのトリガーの無効化または有効化
特定の表のすべてのトリガーを無効化または有効化するには、すべてのトリガーの無効化/すべてのトリガーの有効化ツール、あるいはDISABLE ALL TRIGGERSまたはENABLE ALL TRIGGERS句を指定してALTER TABLE文を使用します。
関連項目:
-
ALTER
TRIGGER
文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 -
ALTER
TABLE
文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
親トピック: トリガーの使用
6.4.1 単一のトリガーの無効化または有効化
単一のトリガーを無効化または有効化するには、トリガーの無効化/トリガーの有効化ツール、あるいはDISABLEまたはENABLE句を指定してALTER TRIGGER文を使用します。
たとえば、次の文ではeval_change_triggerを無効化および有効化します。
ALTER TRIGGER eval_change_trigger DISABLE; ALTER TRIGGER eval_change_trigger ENABLE;
トリガーの無効化/トリガーの有効化ツールを使用するには、次の手順を実行します。
- 「接続」フレームで、hr_connを展開します。
- スキーマ・オブジェクト・タイプのリストで、「トリガー」を展開します。
- トリガーのリストで、対象のトリガーを右クリックします。
- 選択肢のリストで、「無効化」または「有効化」を選択します。
- 「無効化」または「有効化」ウィンドウで、「適用」をクリックします。
- 「確認」ウィンドウで「OK」をクリックします。
親トピック: トリガーの無効化および有効化
6.4.2 単一の表のすべてのトリガーの無効化または有効化
特定の表のすべてのトリガーを無効化または有効化するには、すべてのトリガーの無効化/すべてのトリガーの有効化ツール、あるいはDISABLE ALL TRIGGERSまたはENABLE ALL TRIGGERS句を指定してALTER TABLE文を使用します。
たとえば、次の文ではevaluations表のすべてのトリガーを無効化および有効化します。
ALTER TABLE evaluations DISABLE ALL TRIGGERS; ALTER TABLE evaluations ENABLE ALL TRIGGERS;
すべてのトリガーの無効化/すべてのトリガーの有効化ツールを使用するには、次の手順を実行します。
- 「接続」フレームで、hr_connを展開します。
- スキーマ・オブジェクト・タイプのリストで、「表」を展開します。
- 表のリストで、対象の表を右クリックします。
- 選択肢のリストで、「トリガー」を選択します。
- 選択肢のリストで、「すべて無効化」または「すべて有効化」を選択します。
- 「すべて無効化」または「すべて有効化」ウィンドウで、「適用」をクリックします。
- 「確認」ウィンドウで「OK」をクリックします。
親トピック: トリガーの無効化および有効化
6.5 トリガーのコンパイルおよび依存性について
コンパイルされたトリガーは、トリガーが定義されたスキーマ・オブジェクトに依存します。トリガーが依存するオブジェクトが削除または変更され、トリガーとオブジェクトの不一致が生じた場合、そのトリガーは無効になります。
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;
関連項目:
トリガーのコンパイルおよび依存性の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
親トピック: トリガーの使用
6.6 トリガーの削除
トリガーが依存するオブジェクトを削除する前に、トリガーを削除する必要があります。
トリガーを削除するには、SQL Developerの「接続」フレームと削除ツールまたはDDL文のDROP TRIGGERを使用します。
この文は、トリガーEVAL_CHANGE_TRIGGERを削除します。
DROP TRIGGER EVAL_CHANGE_TRIGGER;
削除ツールを使用してトリガーを削除するには、次の手順を実行します。
- 「接続」フレームで、hr_connを展開します。
- スキーマ・オブジェクト・タイプのリストで、「トリガー」を展開します。
- トリガーのリストで、削除するトリガーの名前を右クリックします。
- 選択肢のリストで、「トリガーの削除」をクリックします。
- 「削除」ウィンドウで、「適用」をクリックします。
- 「確認」ウィンドウで、yをクリックします。
関連項目:
-
DROP TRIGGER文に適用される一般情報は、「データ定義言語(DDL)文について」を参照してください。
-
DROP TRIGGER文の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
親トピック: トリガーの使用