ヘッダーをスキップ

Oracle Database 概要
11gリリース1(11.1)

E05765-03
目次
目次
索引
索引

戻る 次へ

22 トリガー

この章では、データベース・トリガーについて説明します。データベース・トリガーとは、PL/SQLまたはJavaでデータベースに格納されているプロシージャであり、表またはビューが変更された場合、あるいはなんらかのユーザー・アクションやデータベース・システム・アクションが発生した場合に、暗黙的に実行(起動)されます。

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

トリガーの概要

次の操作が発生した場合に起動するトリガーを記述できます。

  1. 発行するユーザーを問わず、特定の表またはビューに対するDML文(INSERTUPDATEDELETE

  2. データベース内の特定または任意のスキーマやユーザーが発行するDDL文(主にCREATEまたはALTER

  3. データベース内の特定または任意のスキーマやユーザーが発行する、ログオンやログオフ、エラーまたは起動や停止などのデータベース・イベント

トリガーは、ストアド・プロシージャに似ています。データベースに格納されているトリガーには、1単位として実行可能なSQLやPL/SQL文を格納でき、また、トリガーは他のストアド・プロシージャを起動できます。ただし、トリガーとプロシージャとでは、起動する方法が異なります。プロシージャは、ユーザー、アプリケーションまたはトリガーによって明示的に実行されます。トリガーは、接続ユーザーや使用中のアプリケーションに関係なく、トリガー・イベントが発生した時点でOracle Databaseによって暗黙的に起動されます。

図22-1に示すデータベース・アプリケーションには、データベースに格納された複数のトリガーを暗黙のうちに起動するSQL文がいくつか含まれています。データベースには、トリガーとそれに対応付けられている表が別々に格納されていることに注目してください。

図22-1    トリガー


画像の説明

また、トリガーはCプロシージャを起動し、計算集中型の操作に使用できます。

関連項目

 

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

トリガーの使用方法

トリガーはOracle Databaseの標準機能を補い、高度にカスタマイズされたデータベース管理システムを提供します。たとえば、トリガーによって、表に対するDML操作を通常の業務時間内のみに制限できます。トリガーには、その他に次のような使用方法があります。

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

トリガーの使用上の注意

トリガーはデータベースのカスタマイズに使用すると便利ですが、必要な場合にのみ使用してください。トリガーを使用しすぎると相互依存性が複雑になるため、大規模アプリケーションのメンテナンスが困難になります。たとえば、トリガーが起動すると、そのトリガー・アクションに含まれるSQL文によって他のトリガーが起動され、トリガーが連鎖状態になることがあります。これにより、意図しない影響を生じるおそれがあります。

トリガーと宣言整合性制約との比較

トリガーと整合性制約を併用すると、任意の整合性規則を定義して規定できます。ただし、トリガーを使用してデータ入力に制約を適用するのは、次の場合に限定してください。

トリガーのコンポーネント

トリガーには次の3つの基本部分があります。それぞれについてこの項で説明します。

図22-2に、各トリガー・コンポーネントを示します。この図は、正確な構文を示すためのものではありません。各トリガー・コンポーネントについては、この後で詳しく説明します。

図22-2    REORDERトリガー


画像の説明

トリガー・イベントまたはトリガーを実行する文

トリガー・イベントまたはトリガーを実行する文とは、トリガーを起動させるSQL文、データベース・イベントまたはユーザー・イベントのことです。トリガー・イベントは、次に示すものの1つ以上からなります。

たとえば、図22-2のトリガーを実行する文は次のとおりです。

... UPDATE OF parts_on_hand ON inventory ...

この文は、inventory表のparts_on_hand列を更新すると、トリガーが起動することを意味します。なお、トリガー・イベントがUPDATE文の場合は、どの列が更新されるとトリガーが起動されるかを示す列リストを指定できます。INSERT文とDELETE文では情報行全体が処理の対象になるため、それらの文には列のリストを指定できません。

トリガー・イベントには、次のように複数のSQL文を指定できます。

... INSERT OR UPDATE OR DELETE OF inventory ...

この場合、inventory表に対してINSERTUPDATEまたはDELETE文を発行すると、トリガーが起動されます。複数のタイプのSQL文でトリガーが起動される場合は、条件述語を使用して、トリガーを実行する文のタイプを検出できます。これにより、トリガーを起動した文のタイプに応じて異なるコードを実行するトリガーを作成できます。

トリガー制限

トリガー制限にはブール式を指定します。トリガーが起動されるには、このブール式がtrueになる必要があります。トリガー制限の評価がfalseまたはunknownになった場合、トリガー・アクションは実行されません。この例では、次のようにしてトリガーを制限しています。

new.parts_on_hand < new.reorder_point 

この場合、引当可能部品の数量が現行の再発注数量より少なくなるまで、トリガーは起動しません。

トリガー・アクション

トリガー・アクションは、SQL文またはコードを含むプロシージャ(PL/SQLブロック、JavaプログラムまたはCコールアウト)です。これらのSQL文やコードは、次のイベントが発生すると実行されます。

ストアド・プロシージャと同様に、トリガー・アクションでは次のことが可能です。

トリガーが行トリガーの場合、トリガー・アクション内の文から、トリガーによって処理されている行の列値にアクセスできます。各列の古い値と新しい値には、相関名によってアクセスできます。

トリガーのタイプ

この項では、様々なタイプのトリガーについて説明します。

行トリガーと文トリガー

トリガーを定義するときに、次のようにトリガー・アクションの実行回数を指定できます。

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

行トリガー

行トリガーは、表がトリガーを実行する文の処理の影響を受けるたびに実行されます。たとえば、UPDATE文が表の複数の行を更新した場合、UPDATE文が処理する行ごとに1つずつ行トリガーが起動されます。トリガーを実行する文の影響を受ける行がなければ、行トリガーは実行されません。

トリガー・アクションのコードが、トリガーを実行する文によって供給されるデータまたは影響を受ける行数に依存する場合には、行トリガーが便利です。たとえば、図22-2は、トリガーを実行する文の影響を受ける各行の値を使用する行トリガーの一例です。

文トリガー

文トリガーは、トリガーを実行する文の影響を受ける表の行数とは関係なく、また、影響を受ける行がない場合にも、トリガーを実行する文の実行ごとに1回起動されます。たとえば、DELETE文が表の複数の行を削除すると、文レベルのDELETEトリガーが1回のみ起動されます。

トリガー・アクションのコードが、トリガーを実行する文によって供給されるデータや、影響を受ける行に依存しない場合には、文トリガーが便利です。文トリガーの使用例を次に示します。

BEFOREおよびAFTERトリガー

トリガーを定義するときに、トリガーのタイミングを指定できます。これは、トリガー・アクションを、トリガーを実行する文の前に実行するのか、後に実行するのかを指定するものです。BEFOREAFTERは、文トリガーと行トリガーの両方に適用されます。

DML文によって起動されるBEFOREトリガーとAFTERトリガーは表にのみ定義でき、ビューには定義できません。ただし、ビューに対してINSERTUPDATEまたはDELETE文を発行すると、そのビューの実表のトリガーが起動されます。DDL文によって起動されるBEFOREトリガーとAFTERトリガーは、データベースまたはスキーマにのみ定義でき、特定の表には定義できません。

関連項目

 

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

BEFOREトリガー

BEFOREトリガーは、トリガー文の実行前にトリガー・アクションを実行します。このタイプのトリガーは、次のような場合によく使用します。

AFTERトリガー

AFTERトリガーは、トリガー文の実行後にトリガー・アクションを実行します。

トリガー・タイプの組合せ

これまでに説明したオプションを使用して、次の4タイプの行トリガーと文トリガーを作成できます。

ある表に対する1つの文に、同じタイプのトリガーを複数指定できます。たとえば、employees表のUPDATE文に対してBEFORE文トリガーを2つ指定できます。同じタイプのトリガーを複数指定することにより、同じ表に対してトリガーを持つ複数のアプリケーションをモジュール化してインストールできます。また、Oracle Databaseマテリアライズド・ビュー・ログはAFTER行トリガーを使用するため、Oracleによって定義されるAFTER行トリガーに加えて、ユーザー独自のAFTER行トリガーを設計できます。

各種DML文(INSERTUPDATEまたはDELETE)に対して、前述のトリガーを必要な数だけ作成できます。

関連項目

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

複合トリガー

複合トリガーは表の単一のトリガーで、次の4つのタイミング・ポイントのそれぞれにアクションを指定できます。

複合トリガーの本体では、各タイミング・ポイント用のコードによるアクセスが可能なPL/SQLの共通の状態がサポートされています。起動文が完了すると、その起動文がエラーの原因になった場合でも、共通の状態は自動的に破棄されます。

複合トリガーの効果は、各タイミング・ポイントに対する単一のトリガーを使用して実現できる効果に似ています(各タイミング・ポイントには、これらの単一のトリガーが共有する状態を保持する補助パッケージを使用して、アクションをコード化する必要があります)。複合トリガーの明らかな長所は、必要なコードが単一のコンパイル・ユニットの中で管理されることですが、さらに重要な長所は、複合トリガーの状態の存続期間が自動的に起動文の継続時間中に制限されるということです。

複合トリガーは、各行の変更を明らかにし、文の後のタイミングで本体として変更に作用するファクトを累積する場合に役立ちます。(テーブルの変更エラーを避けるために)この方法を強制される場合もあります。たとえば、ディテール表での変更に応じて、正規化されていない集計値をマスター表の中で更新する場合、または監査表を更新する場合などは、この方法のパフォーマンスのほうが優れている場合があります。

関連項目

『Oracle Database PL/SQL言語リファレンス』 

INSTEAD OFトリガー

INSTEAD OFトリガーを使用すると、DML文(INSERTUPDATEおよびDELETE)で直接変更できないビューを透過的に変更できるようになります。他のタイプのトリガーとは異なり、Oracle Databaseはトリガー文を実行するかわりにこのトリガーを起動するため、このようなトリガーをINSTEAD OFトリガーと呼びます。

通常のINSERTUPDATEおよびDELETE文をビューに対して記述し、それに応じて基礎となる表が更新されるようにINSTEAD OFトリガーを起動させることができます。INSTEAD OFトリガーは、変更があったビューの行ごとにアクティブ化されます。

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

ビューの変更

ビューを変更する操作では、次のように曖昧な結果を生じることがあります。

オブジェクト・ビューには、その他にも問題があります。たとえば、オブジェクト・ビューの主な使用方法は、マスターとディテールの関連を表すことです。この操作で結合が関係してくるのは避けられませんが、結合の変更は本質的に曖昧です。

その結果、変更可能なビューについては、たくさんの制限事項があります。INSTEAD OFトリガーは、それ以外の手段では変更できないリレーショナル・ビューのみでなく、オブジェクト・ビューに対しても使用できます。

INSTEAD OFトリガーを使用せずにデータを挿入、更新または削除でき、かつ後述の条件に一致する場合、このビューは本質的に変更可能です。ビューが本来は変更可能であっても、挿入、更新または削除する値の妥当性検査を実行する必要があります。この場合にも、INSTEAD OFトリガーを使用できます。変更される行の妥当性チェックがトリガー・コードによって実行され、有効であれば、基礎となる表に変更が伝播されます。

INSTEAD OFトリガーにより、OCIを使用してクライアント側のオブジェクト・ビューのインスタンスを変更することもできます。オブジェクト・ビューによって具体化されたオブジェクトを、クライアント側のオブジェクト・キャッシュ内で変更し、それを永続的な格納領域にフラッシュ・バックするには、オブジェクト・ビューが変更可能でない場合は、INSTEAD OFトリガーを指定する必要があります。ただし、単にオブジェクト・キャッシュ内のビュー・オブジェクトを確保して読み取る場合、これらのトリガーを定義する必要はありません。

関連項目

  • 『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』

  • 『Oracle Call Interfaceプログラマーズ・ガイド』

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

 

変更不可能なビュー

ビュー問合せに次の構成メンバーが含まれている場合、そのビューは本質的に変更不可能であるため、そのビューに対しては挿入、更新または削除を実行できません。

ビューに疑似列または式が含まれる場合、そのビューを更新する唯一の方法は、その疑似列または式を参照しないUPDATE文を使用することです。

関連項目

「更新可能な結合ビュー」 

ネストした表に対するINSTEAD OFトリガー

ビュー内のネストした表の列の要素は、TABLE句で直接変更することはできません。ただし、ビューのネストした表の列にINSTEAD OFトリガーを定義すると、要素を変更できます。ネストした表のトリガーは、その表の要素が更新、挿入または削除すると起動し、基礎となる表に対する実際の変更を処理します。

関連項目

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

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

 

システム・イベントとユーザー・イベントのトリガー

トリガーを使用すると、データベース・イベントに関する情報を、サブスクライバに対して発行できます。アプリケーションは、他のアプリケーションからのメッセージにサブスクライブするのと同様に、データベース・イベントにサブスクライブできます。これらのデータベース・イベントは、次のとおりです。

システム・イベントのトリガーは、データベース・レベルまたはスキーマ・レベルで定義できます。DBMS_AQパッケージは、特定のアクションを実行するデータベース・トリガーの使用例です。たとえば、データベース停止トリガーは、データベース・レベルで次のように定義します。

CREATE TRIGGER register_shutdown 
  ON DATABASE 
  SHUTDOWN 
    BEGIN 
    ...
    DBMS_AQ.ENQUEUE(...); 
    ...
    END; 
    

DDL文またはログオン・イベントおよびログオフ・イベントのトリガーも、データベース・レベルまたはスキーマ・レベルで定義できます。DML文のトリガーは、表またはビューに定義できます。データベース・レベルで定義されたトリガーはすべてのユーザーに対して起動し、スキーマ・レベルまたは表レベルで定義されたトリガーは、トリガー・イベントがそのスキーマまたは表に関連する場合にのみ起動します。

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

イベントの発行

イベントの発行では、Oracle Streams Advanced Queuingのパブリッシュ/サブスクライブ・メカニズムが使用されます。キューは、各種サブスクライバに必要な主題を含むメッセージ・リポジトリの役割を果します。トリガーは、特定のシステム・イベントまたはユーザー・イベントの発生時に、DBMS_AQパッケージを使用してメッセージをエンキューします。

関連項目

  • パブリッシュ/サブスクライブのOracle Streams Advanced Queuing実装の詳細は、『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。

  • DBMS_AQパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

 

イベントの属性

各イベントでは、トリガー・テキスト内で属性を使用できます。たとえば、データベース起動および停止トリガーは、インスタンス番号およびデータベース名の属性を持ち、ログオン・トリガーおよびログオフ・トリガーは、ユーザー名の属性を持ちます。属性をイベント発生時に発行する場合は、トリガーの作成時に、その属性と同じ名前のファンクションを指定できます。属性値は、トリガーの起動時にファンクションまたはペイロードに渡されます。DML文のトリガーの場合は、:OLD列の値によって属性値が:NEW列の値に渡されます。

システム・イベント

トリガーを起動できるシステム・イベントは、インスタンスの起動と停止およびエラー・メッセージに関連しています。起動および停止イベントに対して作成するトリガーは、データベースに対応付ける必要があります。エラー・イベントに対して作成するトリガーは、データベースまたはスキーマに対応付けることができます。

ユーザー・イベント

トリガーを起動できるユーザー・イベントは、ユーザー・ログオンとログオフ、DDL文およびDML文に関連しています。

LOGONイベントおよびLOGOFFイベントのトリガー

LOGONトリガーおよびLOGOFFトリガーは、データベースまたはスキーマに対応付けることができます。その属性には、システム・イベントとユーザー名があり、USERIDUSERNAMEについて簡単な条件を指定できます。

DDL文のトリガー

DDLトリガーは、データベースまたはスキーマに対応付けることができます。その属性には、システム・イベント、スキーマ・オブジェクトのタイプおよび名前があります。ここでは、スキーマ・オブジェクトの型と名前のみでなく、USERIDUSERNAMEなどのファンクションについても簡単な条件を指定できます。

DML文のトリガー

イベント発行用のDMLトリガーは、表に対応付けられます。指定したDML操作が発生する各行に対して起動するように、BEFOREトリガーまたはAFTERトリガーを使用できます。DML文に関連するイベントの発行には、INSTEAD OFトリガーを使用できません。かわりに、INSTEAD OFトリガーによってビューの基礎となる表に生じるDML操作について、 BEFOREトリガーまたはAFTERトリガーを使用してイベントを発行できます。

関連項目

 

トリガーの実行

トリガーは使用可能または使用禁止のいずれかです。

表22-1    トリガーのモード 
トリガーのモード  定義 

使用可能 

使用可能にされているトリガーは、トリガーを実行する文が発行され、トリガー条件(指定されている場合)の評価がTRUEである場合に、そのトリガー・アクションを実行します。 

使用禁止 

使用禁止にされているトリガーは、トリガーを実行する文が発行され、トリガー条件(指定されている場合)の評価がTRUEであっても、そのトリガー・アクションを実行しません。 

使用可能なトリガーの場合、Oracle Databaseは次の処理を自動的に行います。

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

トリガーの実行モデルと整合性制約のチェック

トリガーの本体にある文によって、他のトリガーが起動される場合、そのトリガーは連鎖的と呼びます。Oracle Databaseでは、最高32個のトリガーが同時に連鎖できます。

リレーショナル・データベースでは、SQL文によって処理される行の順序が保証されません。そのため、行の処理の順序に依存するトリガーは作成しないでください。

関連項目

トリガーの作成およびそれらが起動される順序の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 

トリガーのデータ・アクセス

トリガーが起動されると、トリガー・アクション内で参照される表は、他のユーザーのトランザクション内のSQL文によって変更されている最中である可能性があります。トリガー内で実行されるSQL文は、常に単独のSQL文と同じ規則に従います。起動されたトリガーが読取り(問合せ)または書込み(更新)の対象にする値が、まだコミットされていないトランザクションによって変更されたものである場合、起動されたトリガーの本体にあるSQL文は、次のガイドラインに従います。

PL/SQLトリガーの記憶域

PL/SQLトリガーは、ストアド・プロシージャと同じように、コンパイル済の形式でOracle Databaseに格納されます。CREATE TRIGGER文がコミットされると、コンパイル済PL/SQLコードがデータベースに格納され、トリガーのソース・コードは共有プールからフラッシュされます。

関連項目

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

トリガーの実行

Oracle Databaseは、サブプログラムの実行と同じ手順を使用してトリガーを内部的に実行します。両者の唯一の違いは、ユーザーがトリガー文を実行する権限を持っていれば、トリガーを起動する権限が付与されることです。この違いを除き、トリガーはストアド・サブプログラムと同じ方法でチェックされ、実行されます。

関連項目

ストアド・サブプログラムの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 

トリガーの依存性のメンテナンス

プロシージャと同様に、トリガーも参照しているオブジェクトに依存します。トリガー・アクションで参照されるスキーマ・オブジェクトに対するトリガーの依存性は、Oracle Databaseによって自動的に管理されます。トリガーの依存性についての問題は、ストアド・プロシージャの依存性についての問題と同じです。トリガーは、ストアド・プロシージャと同様に扱われます。これらは、データ・ディクショナリに挿入されます。

関連項目

第6章「スキーマ・オブジェクトの依存性」 


戻る 次へ
Oracle
Copyright © 1993, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引