Oracle Database 概要 11gリリース1(11.1) E05765-03 |
|
この章では、データベース・トリガーについて説明します。データベース・トリガーとは、PL/SQLまたはJavaでデータベースに格納されているプロシージャであり、表またはビューが変更された場合、あるいはなんらかのユーザー・アクションやデータベース・システム・アクションが発生した場合に、暗黙的に実行(起動)されます。
この章の内容は、次のとおりです。
次の操作が発生した場合に起動するトリガーを記述できます。
INSERT
、UPDATE
、DELETE
)
CREATE
またはALTER
)
トリガーは、ストアド・プロシージャに似ています。データベースに格納されているトリガーには、1単位として実行可能なSQLやPL/SQL文を格納でき、また、トリガーは他のストアド・プロシージャを起動できます。ただし、トリガーとプロシージャとでは、起動する方法が異なります。プロシージャは、ユーザー、アプリケーションまたはトリガーによって明示的に実行されます。トリガーは、接続ユーザーや使用中のアプリケーションに関係なく、トリガー・イベントが発生した時点でOracle Databaseによって暗黙的に起動されます。
図22-1に示すデータベース・アプリケーションには、データベースに格納された複数のトリガーを暗黙のうちに起動するSQL文がいくつか含まれています。データベースには、トリガーとそれに対応付けられている表が別々に格納されていることに注目してください。
また、トリガーはCプロシージャを起動し、計算集中型の操作に使用できます。
この項の内容は、次のとおりです。
トリガーはOracle Databaseの標準機能を補い、高度にカスタマイズされたデータベース管理システムを提供します。たとえば、トリガーによって、表に対するDML操作を通常の業務時間内のみに制限できます。トリガーには、その他に次のような使用方法があります。
この項の内容は、次のとおりです。
トリガーはデータベースのカスタマイズに使用すると便利ですが、必要な場合にのみ使用してください。トリガーを使用しすぎると相互依存性が複雑になるため、大規模アプリケーションのメンテナンスが困難になります。たとえば、トリガーが起動すると、そのトリガー・アクションに含まれるSQL文によって他のトリガーが起動され、トリガーが連鎖状態になることがあります。これにより、意図しない影響を生じるおそれがあります。
トリガーと整合性制約を併用すると、任意の整合性規則を定義して規定できます。ただし、トリガーを使用してデータ入力に制約を適用するのは、次の場合に限定してください。
トリガーには次の3つの基本部分があります。それぞれについてこの項で説明します。
図22-2に、各トリガー・コンポーネントを示します。この図は、正確な構文を示すためのものではありません。各トリガー・コンポーネントについては、この後で詳しく説明します。
トリガー・イベントまたはトリガーを実行する文とは、トリガーを起動させるSQL文、データベース・イベントまたはユーザー・イベントのことです。トリガー・イベントは、次に示すものの1つ以上からなります。
INSERT
、UPDATE
、またはDELETE
文
CREATE
、ALTER
またはDROP
文
たとえば、図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
表に対してINSERT
、UPDATE
または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
は、文トリガーと行トリガーの両方に適用されます。
DML文によって起動されるBEFORE
トリガーとAFTER
トリガーは表にのみ定義でき、ビューには定義できません。ただし、ビューに対してINSERT
、UPDATE
またはDELETE
文を発行すると、そのビューの実表のトリガーが起動されます。DDL文によって起動されるBEFORE
トリガーとAFTER
トリガーは、データベースまたはスキーマにのみ定義でき、特定の表には定義できません。
関連項目
|
この項の内容は、次のとおりです。
BEFORE
トリガーは、トリガー文の実行前にトリガー・アクションを実行します。このタイプのトリガーは、次のような場合によく使用します。
BEFORE
トリガーを使用することにより、トリガー・アクションで例外が発生した場合に、トリガー文で無駄な処理を実行して結果的にロールバックすることになるのを避けられます。
INSERT
またはUPDATE
文を実行する前に、特定の列値を調べる場合。
AFTER
トリガーは、トリガー文の実行後にトリガー・アクションを実行します。
これまでに説明したオプションを使用して、次の4タイプの行トリガーと文トリガーを作成できます。
トリガー文を実行する前にトリガー・アクションが実行されます。
トリガーを実行する文の影響を受ける各行が修正され、該当する整合性制約の検査の前に、トリガー条件に違反していないかぎりトリガー・アクションが実行されます。
トリガー文を実行し、遅延整合性制約を適用した後に、トリガー・アクションが実行されます。
トリガーを実行する文の影響を受ける各行が修正され、該当する整合性制約が適用された後で、トリガー制限に違反していないかぎり現在行に対してトリガー・アクションが実行されます。BEFORE
行トリガーと異なり、AFTER
行トリガーは、行をロックします。
ある表に対する1つの文に、同じタイプのトリガーを複数指定できます。たとえば、employees
表のUPDATE
文に対してBEFORE
文トリガーを2つ指定できます。同じタイプのトリガーを複数指定することにより、同じ表に対してトリガーを持つ複数のアプリケーションをモジュール化してインストールできます。また、Oracle Databaseマテリアライズド・ビュー・ログはAFTER
行トリガーを使用するため、Oracleによって定義されるAFTER
行トリガーに加えて、ユーザー独自のAFTER
行トリガーを設計できます。
各種DML文(INSERT
、UPDATE
またはDELETE
)に対して、前述のトリガーを必要な数だけ作成できます。
複合トリガーは表の単一のトリガーで、次の4つのタイミング・ポイントのそれぞれにアクションを指定できます。
複合トリガーの本体では、各タイミング・ポイント用のコードによるアクセスが可能なPL/SQLの共通の状態がサポートされています。起動文が完了すると、その起動文がエラーの原因になった場合でも、共通の状態は自動的に破棄されます。
複合トリガーの効果は、各タイミング・ポイントに対する単一のトリガーを使用して実現できる効果に似ています(各タイミング・ポイントには、これらの単一のトリガーが共有する状態を保持する補助パッケージを使用して、アクションをコード化する必要があります)。複合トリガーの明らかな長所は、必要なコードが単一のコンパイル・ユニットの中で管理されることですが、さらに重要な長所は、複合トリガーの状態の存続期間が自動的に起動文の継続時間中に制限されるということです。
複合トリガーは、各行の変更を明らかにし、文の後のタイミングで本体として変更に作用するファクトを累積する場合に役立ちます。(テーブルの変更エラーを避けるために)この方法を強制される場合もあります。たとえば、ディテール表での変更に応じて、正規化されていない集計値をマスター表の中で更新する場合、または監査表を更新する場合などは、この方法のパフォーマンスのほうが優れている場合があります。
INSTEAD
OF
トリガーを使用すると、DML文(INSERT
、UPDATE
およびDELETE
)で直接変更できないビューを透過的に変更できるようになります。他のタイプのトリガーとは異なり、Oracle Databaseはトリガー文を実行するかわりにこのトリガーを起動するため、このようなトリガーをINSTEAD
OF
トリガーと呼びます。
通常のINSERT
、UPDATE
およびDELETE
文をビューに対して記述し、それに応じて基礎となる表が更新されるようにINSTEAD
OF
トリガーを起動させることができます。INSTEAD
OF
トリガーは、変更があったビューの行ごとにアクティブ化されます。
この項の内容は、次のとおりです。
ビューを変更する操作では、次のように曖昧な結果を生じることがあります。
オブジェクト・ビューには、その他にも問題があります。たとえば、オブジェクト・ビューの主な使用方法は、マスターとディテールの関連を表すことです。この操作で結合が関係してくるのは避けられませんが、結合の変更は本質的に曖昧です。
その結果、変更可能なビューについては、たくさんの制限事項があります。INSTEAD
OF
トリガーは、それ以外の手段では変更できないリレーショナル・ビューのみでなく、オブジェクト・ビューに対しても使用できます。
INSTEAD
OF
トリガーを使用せずにデータを挿入、更新または削除でき、かつ後述の条件に一致する場合、このビューは本質的に変更可能です。ビューが本来は変更可能であっても、挿入、更新または削除する値の妥当性検査を実行する必要があります。この場合にも、INSTEAD
OF
トリガーを使用できます。変更される行の妥当性チェックがトリガー・コードによって実行され、有効であれば、基礎となる表に変更が伝播されます。
INSTEAD
OF
トリガーにより、OCIを使用してクライアント側のオブジェクト・ビューのインスタンスを変更することもできます。オブジェクト・ビューによって具体化されたオブジェクトを、クライアント側のオブジェクト・キャッシュ内で変更し、それを永続的な格納領域にフラッシュ・バックするには、オブジェクト・ビューが変更可能でない場合は、INSTEAD
OF
トリガーを指定する必要があります。ただし、単にオブジェクト・キャッシュ内のビュー・オブジェクトを確保して読み取る場合、これらのトリガーを定義する必要はありません。
ビュー問合せに次の構成メンバーが含まれている場合、そのビューは本質的に変更不可能であるため、そのビューに対しては挿入、更新または削除を実行できません。
ビューに疑似列または式が含まれる場合、そのビューを更新する唯一の方法は、その疑似列または式を参照しないUPDATE
文を使用することです。
ビュー内のネストした表の列の要素は、TABLE
句で直接変更することはできません。ただし、ビューのネストした表の列にINSTEAD
OF
トリガーを定義すると、要素を変更できます。ネストした表のトリガーは、その表の要素が更新、挿入または削除すると起動し、基礎となる表に対する実際の変更を処理します。
トリガーを使用すると、データベース・イベントに関する情報を、サブスクライバに対して発行できます。アプリケーションは、他のアプリケーションからのメッセージにサブスクライブするのと同様に、データベース・イベントにサブスクライブできます。これらのデータベース・イベントは、次のとおりです。
システム・イベントのトリガーは、データベース・レベルまたはスキーマ・レベルで定義できます。DBMS_AQ
パッケージは、特定のアクションを実行するデータベース・トリガーの使用例です。たとえば、データベース停止トリガーは、データベース・レベルで次のように定義します。
CREATE TRIGGER register_shutdown ON DATABASE SHUTDOWN BEGIN ... DBMS_AQ.ENQUEUE(...); ... END;
DDL文またはログオン・イベントおよびログオフ・イベントのトリガーも、データベース・レベルまたはスキーマ・レベルで定義できます。DML文のトリガーは、表またはビューに定義できます。データベース・レベルで定義されたトリガーはすべてのユーザーに対して起動し、スキーマ・レベルまたは表レベルで定義されたトリガーは、トリガー・イベントがそのスキーマまたは表に関連する場合にのみ起動します。
この項の内容は、次のとおりです。
イベントの発行では、Oracle Streams Advanced Queuingのパブリッシュ/サブスクライブ・メカニズムが使用されます。キューは、各種サブスクライバに必要な主題を含むメッセージ・リポジトリの役割を果します。トリガーは、特定のシステム・イベントまたはユーザー・イベントの発生時に、DBMS_AQ
パッケージを使用してメッセージをエンキューします。
各イベントでは、トリガー・テキスト内で属性を使用できます。たとえば、データベース起動および停止トリガーは、インスタンス番号およびデータベース名の属性を持ち、ログオン・トリガーおよびログオフ・トリガーは、ユーザー名の属性を持ちます。属性をイベント発生時に発行する場合は、トリガーの作成時に、その属性と同じ名前のファンクションを指定できます。属性値は、トリガーの起動時にファンクションまたはペイロードに渡されます。DML文のトリガーの場合は、:OLD
列の値によって属性値が:NEW
列の値に渡されます。
トリガーを起動できるシステム・イベントは、インスタンスの起動と停止およびエラー・メッセージに関連しています。起動および停止イベントに対して作成するトリガーは、データベースに対応付ける必要があります。エラー・イベントに対して作成するトリガーは、データベースまたはスキーマに対応付けることができます。
STARTUP
トリガーは、インスタンスによってデータベースがオープンされるときに起動します。この属性には、システム・イベント、インスタンス番号およびデータベース名があります。
SHUTDOWN
トリガーは、サーバーがインスタンスの停止操作を開始する直前に起動します。このトリガーを使用して、データベースの停止時にサブスクライバ・アプリケーションを完全に停止できます。インスタンスが異常停止する場合、このトリガーは起動しません。SHUTDOWN
トリガーの属性には、システム・イベント、インスタンス番号およびデータベース名があります。
SERVERERROR
トリガーは、特定のエラーの発生時、または、エラー番号を指定しなければ任意のエラーの発生時に起動します。このトリガーの属性には、システム・イベントとエラー番号があります。
DB_ROLE_CHANGE
トリガーは、Data Guard構成でロール遷移(フェイルオーバーまたはスイッチオーバー)が発生したときに起動します。このトリガーでは、ロール遷移発生時にユーザーに通知されるため、新規プライマリ・データベースでクライアント接続を処理でき、アプリケーションは引き続き動作できます。
トリガーを起動できるユーザー・イベントは、ユーザー・ログオンとログオフ、DDL文およびDML文に関連しています。
LOGON
トリガーおよびLOGOFF
トリガーは、データベースまたはスキーマに対応付けることができます。その属性には、システム・イベントとユーザー名があり、USERID
とUSERNAME
について簡単な条件を指定できます。
DDLトリガーは、データベースまたはスキーマに対応付けることができます。その属性には、システム・イベント、スキーマ・オブジェクトのタイプおよび名前があります。ここでは、スキーマ・オブジェクトの型と名前のみでなく、USERID
やUSERNAME
などのファンクションについても簡単な条件を指定できます。
イベント発行用のDMLトリガーは、表に対応付けられます。指定したDML操作が発生する各行に対して起動するように、BEFORE
トリガーまたはAFTER
トリガーを使用できます。DML文に関連するイベントの発行には、INSTEAD
OF
トリガーを使用できません。かわりに、INSTEAD
OF
トリガーによってビューの基礎となる表に生じるDML操作について、 BEFORE
トリガーまたはAFTER
トリガーを使用してイベントを発行できます。
関連項目
|
トリガーは使用可能または使用禁止のいずれかです。
トリガーのモード | 定義 |
---|---|
使用可能 |
使用可能にされているトリガーは、トリガーを実行する文が発行され、トリガー条件(指定されている場合)の評価が |
使用禁止 |
使用禁止にされているトリガーは、トリガーを実行する文が発行され、トリガー条件(指定されている場合)の評価が |
使用可能なトリガーの場合、Oracle Databaseは次の処理を自動的に行います。
この項の内容は、次のとおりです。
トリガーの本体にある文によって、他のトリガーが起動される場合、そのトリガーは連鎖的と呼びます。Oracle Databaseでは、最高32個のトリガーが同時に連鎖できます。
リレーショナル・データベースでは、SQL文によって処理される行の順序が保証されません。そのため、行の処理の順序に依存するトリガーは作成しないでください。
トリガーが起動されると、トリガー・アクション内で参照される表は、他のユーザーのトランザクション内のSQL文によって変更されている最中である可能性があります。トリガー内で実行されるSQL文は、常に単独のSQL文と同じ規則に従います。起動されたトリガーが読取り(問合せ)または書込み(更新)の対象にする値が、まだコミットされていないトランザクションによって変更されたものである場合、起動されたトリガーの本体にあるSQL文は、次のガイドラインに従います。
PL/SQLトリガーは、ストアド・プロシージャと同じように、コンパイル済の形式でOracle Databaseに格納されます。CREATE TRIGGER
文がコミットされると、コンパイル済PL/SQLコードがデータベースに格納され、トリガーのソース・コードは共有プールからフラッシュされます。
Oracle Databaseは、サブプログラムの実行と同じ手順を使用してトリガーを内部的に実行します。両者の唯一の違いは、ユーザーがトリガー文を実行する権限を持っていれば、トリガーを起動する権限が付与されることです。この違いを除き、トリガーはストアド・サブプログラムと同じ方法でチェックされ、実行されます。
プロシージャと同様に、トリガーも参照しているオブジェクトに依存します。トリガー・アクションで参照されるスキーマ・オブジェクトに対するトリガーの依存性は、Oracle Databaseによって自動的に管理されます。トリガーの依存性についての問題は、ストアド・プロシージャの依存性についての問題と同じです。トリガーは、ストアド・プロシージャと同様に扱われます。これらは、データ・ディクショナリに挿入されます。
|
Copyright © 1993, 2008 Oracle Corporation. All Rights Reserved. |
|