トリガーのコーディングトリガーとは、データベース内に格納され、何かが発生したときに暗黙的に実行つまり起動されるプロシージャです。これまでトリガーは、表またはビューに対してINSERT、UPDATEまたはDELETEが発生したときのPL/SQLブロックの実行をサポートしてきました。トリガーは、DATABASEおよびSCHEMAに対するシステム・イベントおよびその他のデータ・イベントをサポートしています。Databaseでは、PL/SQLプロシージャまたはJavaプロシージャの実行もサポートします。OFトリガーおよびシステム・トリガー(DATABASEおよびSCHEMAに対するトリガー)について説明します。内容は次のとおりです。トリガーの設計トリガーの作成トリガー本体のコーディングトリガーのコンパイルトリガーの変更トリガーの使用可能および使用禁止トリガーに関する情報のリストトリガー・アプリケーションの例トリガーを介したシステム・イベントに対する応答トリガーの設計トリガーを設計するときは、次のガイドラインを使用してください。トリガーは、ある操作が実行されたときに、関係するアクションが確実に実行されるようにする場合に使用してください。Databaseにすでに組み込まれている機能は、トリガーに重複定義しないでください。宣言整合性制約で同じチェックができる場合、不良データを拒否するためにトリガーを定義しないでください。トリガーのサイズを制限してください。トリガーのロジックが60行をはるかに超えるPL/SQLコードを必要とする場合は、コードの大部分をストアド・プロシージャに組み込んで、トリガーからそのプロシージャをコールすることをお薦めします。ユーザーまたはデータベース・アプリケーションのどちらがトリガーを実行する文を発行するかに関係なく、トリガーを実行する文に対して起動される集中的グローバル操作にのみトリガーを使用してください。再帰トリガーは作成しないでください。UPDATE文トリガーをEmp_tab表に作成すると、このトリガーはメモリー不足になるまで再帰的に起動し続けます。DATABASEに対するトリガーは、慎重に使用してください。このようなトリガーは、トリガーの対象イベントが発生するたびに、すべてのユーザーに対して実行されます。TRIGGER文を使用して作成します。Managerなどの対話型ツールで使用できます。TRIGGER文をアクティブにするには、最終行にスラッシュ(/)を1つ付けます。次の文は、Emp_tab表に対するトリガーを作成します。sal_diff);END;/DML操作(INSERT文、UPDATE文およびDELETE文)が表に実行されると、トリガーが起動されます。トリガーを起動する操作の組合せは選択できます。トリガーは、BEFOREキーワードを使用するため、表に入る前に新しい値にアクセスできます。:NEW.column_nameに割り当てることによって、簡単に修正されたエラーがある場合は、その値を変更できます。トリガーは、初期変更が適用され、表が一貫性のある状態に戻った後にのみ同じ表の問合せまたは変更を実行できるため、トリガーでこれらの操作をする場合は、AFTERキーワードを使用します。ROW句を使用するため、複数行の更新または削除時などに複数回実行される場合があります。操作が発生したという事実のみを記録し、各行のデータを調べない場合は、この句を省略します。トリガーの作成後に、次のSQL文を入力します。10;このSQL文により、更新される行ごとにトリガーが1回起動され、各行に対して新しい給与、古い給与およびその差異が出力されます。REPLACE文)は正常に実行されません。注意トリガーのサイズは、32KB未満で指定してください。次の項では、トリガーの各要素の指定方法を説明します。TRIGGER文の例の詳細は、「トリガー・アプリケーションの例」を参照してください。トリガーの種類トリガーは、ストアドPL/SQLブロックか、あるいは表、ビュー、スキーマまたはデータベース自体に関連付けられるPL/SQL、CまたはJavaのプロシージャです。Databaseでは、指定されたイベントが発生したときに、トリガーを自動的に実行します。イベントはシステム・イベントか、または表に対して発行されるDML文の形態をとります。トリガーは次のいずれかです。DATABASEの場合は、トリガーはイベントごとにすべてのユーザーに対して起動されます。SCHEMAの場合は、トリガーはイベントごとに特定ユーザーに対して起動されます。SQLリファレンス』を参照してください。次のいずれかに対して起動されるトリガーを作成できます。DML文(DELETE、INSERT、UPDATE)DDL文(CREATE、ALTER、DROP)データベース処理(SERVERERROR、LOGON、LOGOFF、STARTUP、SHUTDOWN)システム・イベント属性の取得トリガーが起動されるときに、イベント固有の特定の属性を取得できます。DATABASEに対してトリガーを作成するということは、トリガーになるイベントがユーザーの有効範囲の外にある(たとえば、データベースのSTARTUPおよびSHUTDOWN)ことを意味し、そのトリガーはすべてのユーザーに適用されます(たとえば、LOGONイベントに対してDBAにより作成されるトリガー)。SCHEMAに対してトリガーを作成するということは、トリガーが現行のユーザーのスキーマ内に作成され、そのユーザーに対してのみ起動されることを意味します。それぞれのトリガーに関して、DMLおよびシステム・イベントに対して発行を指定できます。「トリガーを介したシステム・イベントに対する応答」トリガーのネーミングトリガーの名前は、同一スキーマ内の他のトリガーに対して一意である必要があります。他のスキーマ・オブジェクト(表、ビュー、プロシージャなど)名とは重複してもかまいません。表とトリガーに同じ名前を付けることもできます(ただし、間違えやすいため、違う名前を付けることをお薦めします)。トリガーが起動するタイミングトリガーは、トリガーを実行する文に基づいて起動されます。トリガーを実行する文では次のものを指定します。SQL文あるいはトリガー本体を起動するシステム・イベント、データベース・イベントまたはDDLイベント。オプションとして、DELETE、INSERTおよびUPDATEがあります。これらのオプションのうちのいずれか、またはすべてをトリガーを実行する文の仕様部に組み込むことができます。トリガーに関連付けられる表、ビュー、DATABASEまたはSCHEMA。注意トリガーを実行する文には、表またはビューを1つのみ指定できます。OFオプションを使用する場合、トリガーを実行する文にはビューのみを指定します。OFオプションのみを使用できます。PRINT_SALARY_CHANGESトリガーは、Emp_tab表に対してDELETE、INSERTまたはUPDATEのいずれかが実行されたときに起動されます。次のいずれかの文によって、前述の例で使用されているPRINT_SALARY_CHANGESトリガーが実行されます。;インポートおよびSQL*Loaderによるトリガー起動INSERTトリガーは、SQL*Loaderによる通常のロード中に起動されます。(ダイレクト・ロードの場合、トリガーはロードの前に使用禁止になります。)IMPコマンドのIGNOREパラメータは、インポート中にトリガーを起動するかどうかを決定します。IGNORE=N(デフォルト)および表がすでに存在する場合は、インポートでは表は変更されず、既存のトリガーは起動されません。表が存在しない場合は、トリガーが定義される前にインポートによって表が作成されてロードされるため、この場合もトリガーは起動されません。IGNORE=Yの場合は、インポートによって行が既存の表にロードされます。既存のトリガーがすべて起動され、インポートされたデータを含めるために索引が更新されます。列リストのUPDATEトリガーに対する影響UPDATE文が列のリストを含む場合があります。トリガーを実行する文に列リストが含まれる場合、トリガーは指定された列の1つが更新される場合にのみ起動されます。トリガーを実行する文で列リストが省略された場合、トリガーは関連付けられた表のいずれかの列が更新された場合に起動されます。INSERTまたはDELETEトリガーを実行する文に列リストを指定することはできません。前述のPRINT_SALARY_CHANGESトリガーの例では、トリガーを実行する文に列リストを指定することができます。OFトリガーを指定してUPDATEに列リストを指定できません。OF句に指定された列がオブジェクト列の場合は、オブジェクトの属性のどれかが変更された場合にもトリガーが起動されます。OF句はコレクション列には指定できません。TRIGGER文にBEFOREまたはAFTERオプションを指定して、実行中のトリガー文によってトリガー本体が起動されるタイミングを指定できます。TRIGGER文では、トリガーを実行する文の直前にBEFOREまたはAFTERオプションを指定します。前述の例では、PRINT_SALARY_CHANGESトリガーがBEFOREトリガーです。一般に、BEFOREトリガーまたはAFTERトリガーは、それぞれ次のような場合に使用します。行データがディスクに書き込まれる前に行を変更する場合は、BEFORE行トリガーを使用します。行IDを使用して取得および操作を実行する場合は、AFTER行トリガーを使用します。注意BEFORE行トリガーを使用すると、AFTER行トリガーより多少効率が上がります。AFTER行トリガーでは、影響を受けるデータ・ブロックをトリガーのために1回読み込み(論理的な読込みであり、物理的な読込みではない)、トリガーを実行する文のために再び読み込む必要があります。BEFORE行トリガーでは、データ・ブロックを、トリガーを実行する文およびトリガーの両方に対して1回読み込むのみで済みます。DatabaseはSAVEPOINTまでの透過的ROLLBACKを実行して、更新を再起動します。文が正常に完了するまで、これは何度も行われる可能性があります。文が再起動されるたびに、BEFORE文トリガーが再起動されます。セーブポイントまでのロールバックでは、トリガー内で参照されるパッケージ変数への変更は取り消されません。パッケージには、このような状況を検出するためのカウンタ変数を含める必要があります。トリガーの順序リレーショナル・データベースは、SQL文による行の処理順序を保証しません。したがって、行の処理順序に基づくトリガーは作成しないでください。グローバル変数の現在の値が、行トリガーによって処理される行に依存する場合は、行トリガー内のグローバル・パッケージ変数に値を割り当てないでください。グローバル・パッケージ変数の値がトリガー内で更新される場合は、これらの変数をBEFORE文トリガー内で初期化するようにしてください。トリガー本体内の文によって他のトリガーが起動される場合、それらのトリガーはカスケードしているといいます。Databaseでは、一度に最大32個のトリガーをカスケードできます。OPEN_CURSORS初期化パラメータを使用して、カスケード可能なトリガーの数を制限することもできます。これは、トリガーを実行するたびにカーソルがオープンされるためです。トリガーの評価順序トリガーは、インラインで、またはプロシージャをコールすることによって一連の操作を実行できますが、同じ型の複数のトリガーを使用すると、同じ表に対するトリガーを持つアプリケーションのインストールをモジュール化できるため、データベース管理が強化されます。Databaseは、別の型のトリガーを実行する前に、同じ型のすべてのトリガーを実行します。Databaseでは任意の順序を選択してこれらのトリガーを実行します。Database概要』を参照してください。後続の各トリガーは、前に起動されたトリガーが変更した内容を参照します。個々のトリガーは、old値およびnew値を参照できます。old値は元の値で、new値は一番最後に起動されたUPDATEトリガーまたはINSERTトリガーが設定した現在の値です。トリガーされた複数のアクションが特定の順序で確実に実行されるようにするには、これらのアクションをまとめて1つのトリガーに統合する必要があります(たとえば、トリガーが一連のプロシージャをコールする方法を使用します)。OFトリガー)更新可能なビューとは、基礎となる表にDMLを実行できるビューです。OFトリガーが必要なビュー」の項に示されている構造体の1つ以上から作成されているビューは更新できません。OFトリガーを使用して更新可能にできます。OFトリガーを使用すると、UPDATE文、INSERT文およびDELETE文では直接変更できないビューを透過的に変更できます。Databaseはトリガーを実行する文を実行するかわりにこのトリガーを起動するためです。このトリガーは、対象となる操作を判断し、UPDATE、INSERTまたはDELETE操作を基礎となる表に対して直接実行する必要があります。OFトリガーがバックグラウンドで動作します。OFトリガーをアクティブにできるのは、それぞれの行に対してのみです。OFオプションが使用できるのは、ビューに対して作成されるトリガーのみです。BEFOREオプションおよびAFTERオプションは、ビューに対して作成されるトリガーには使用できません。OFトリガーを使用して行われる場合は施行されません。OFトリガー本体でチェックを施行する必要があります。OFトリガーが必要なビュービューの問合せに次のいずれかの構造体が含まれている場合、UPDATE文、INSERT文またはDELETE文を使用してビューを変更できません。Database管理者ガイド』に記述のある結合(一部例外あり)疑似列または式が含まれたビューを更新するには、疑似列または式のどちらも参照しないUPDATE文のみを使用します。次のデータ構造を設定しないと機能しない例もあります。OFトリガーを示します。MANAGER_INFOビューに行を挿入するというアクションでは、まず、MANAGER_INFOの導出元の実表に該当する行があるかどうかを調べます。その後、必要に応じて、新しい行を挿入するか、または既存の行を更新します。同じようなトリガーを使用して、UPDATEおよびDELETE用のアクションを指定できます。OFトリガーによって、クライアント側でOCIコールを介してオブジェクト・ビューのインスタンスを変更できます。OFトリガーを指定する必要があります。オブジェクトが読込み専用の場合は、トリガーを定義して確保する必要はありません。OFトリガーは、ネストした表のビューの列に対しても作成できます。このトリガーは、ネストした表の要素を更新する手段を提供します。このトリガーは、ネストした表の各更新対象要素に対して起動されます。トリガー内の行相関変数が、ネストした表の要素に対応します。この種のトリガーは、変更対象のネストした表を含む親である行にアクセスするための追加相関名も提供します。注意このトリガーの特長は次のとおりです。ビューの中のネストした表の列に対してのみ定義できます。ネストした表の要素が、THE()句またはTABLE()句を使用して変更されるときにのみ起動されます。ビューに対してDML文が実行されるときには起動されません。社員用のネストした表を含む部門ビューについて考えてみます。d;CAST(MULTISET..)演算子によって、部門ごとに社員の多重集合が作成されます。トリガーを定義して処理できます。次の例は、挿入トリガーの作成方法を示します。:Department.Deptno);END;ネストした表にINSERTが実行されるとトリガーが起動され、Emp_tab表が正しい値で埋められます。10000);この例の:department.deptno相関変数には、値10が入ります。ROWオプションによって、トリガーが行トリガーになるか文トリガーになるかが決定されます。ROWを指定すると、トリガーを実行する文によって影響を受ける表の各行に対してトリガーが1回起動されます。ROWオプションを指定しないと、トリガーは該当する個々の文に対して1回のみ起動され、その文によって影響される各行に対して別々に起動されることはありません。次のようなトリガーを定義します。次のようなデータ構造を設定しないと機能しない例もあります。SAL');END;次に、次のSQL文を入力します。20;部門20に5人の社員がいる場合、この文が入力されるとトリガーが5回起動されます。これは、5つの行が影響を受けるためです。次のトリガーは、Emp_tab表の各UPDATEに対して1回のみ起動します。Database概要』を参照してください。文レベル・トリガーは、文全体の妥当性チェックを実行するときに有効です。条件に基づいたトリガーの起動(WHEN句)行トリガー定義にトリガー制約をオプションで指定できます。これには、WHEN句にSQLのブール式を指定します。注意WHEN句は、文トリガーの定義に含めることはできません。このオプションを指定すると、WHEN句の式がトリガーの処理対象となる行ごとに評価されます。行に対して式がTRUEと評価されると、その行のかわりにトリガー本体が起動されます。TRUEと評価された場合(NULLの場合のように不明な場合)、その行に対してトリガー本体は起動されません。WHEN句の評価は、トリガーを実行するSQL文の実行には影響しません(WHEN句の式がFALSEと評価されても、トリガーを実行する文はロールバックされません)。PRINT_SALARY_CHANGESトリガーでは、Empnoの新しい値が0(ゼロ)、NULLまたは負の場合、トリガー本体は実行されません。具体的な例としては、ある列の値が他の列の値より小さいかどうかテストする場合があります。行トリガーのWHEN句の式に相関名を指定できます。相関名については後述します。WHEN句の式はSQL式にする必要があり、副問合せを含むことはできません。WHEN句では、PL/SQL式(ユーザー定義ファンクションを含む)は使用できません。OFトリガーには指定できません。トリガー本体のコーディングトリガー本体は、SQL文またはPL/SQL文を含めることができるCALLプロシージャまたはPL/SQLブロックです。CALLプロシージャは、PL/SQLまたはPL/SQLラッパーにカプセル化されたJavaプロシージャのどちらかです。これらの文は、トリガーを実行する文が入力され、トリガー制約(含まれている場合)がTRUEと評価された場合に実行されます。行トリガーのトリガー本体には、相関名、REFERENCEINGオプション、条件述語のINSERTING、DELETING、UPDATINGなどの特殊な要素を含められます。これらの要素は、PL/SQLブロックのコードにも含めることができます。注意INSERTING、DELETING、UPDATING条件述語は、CALLプロシージャには使用できません。使用できるのはPL/SQLブロック内のみです。次のようなデータ構造を設定しないと機能しない例もあります。トリガーからのJavaプロシージャのコールトリガーは、PL/SQLで宣言されますが、Javaなどの他の言語でプロシージャをコールすることができます。:old.Ename)/対応するJavaファイルはthjvTriggers.javaです。}}行トリガーでの列値のアクセス行トリガーのトリガー本体では、PL/SQLコードおよびSQL文は、トリガーを実行する文によって影響を受ける現在の行に含まれるold列値およびnew列値にアクセスできます。変更される表の各列に2つの相関名(old列値用およびnew列値用に1つずつ)があります。トリガーを実行する文の種類によっては、相関名が意味を持たない場合もあります。INSERT文によって起動されるトリガーは、new列値に対してのみ意味のあるアクセスを行います。行はINSERTによって作成されるため、old値はNULLです。UPDATE文によって起動されるトリガーは、BEFOREおよびAFTERの両方の行トリガーで、old列値およびnew列値の両方にアクセスします。DELETE文によって起動されるトリガーは、:old列値に対してのみ意味のあるアクセスを行います。行を削除すると行はなくなるため、:new値はNULLです。:new値を変更しようとすると、ORA-4084が発生するため、:new値は変更できません。元の列値は、列名の前にold修飾子を指定して参照し、新しい列値は列名の前にnew修飾子を指定して参照します。トリガーを実行する文がEmp_tab表(列SAL、COMMなどを持つ)に対応付けられている場合、トリガー本体に文を含めることができます。...old値およびnew値は、BEFOREおよびAFTER行トリガー内で使用できます。new列値はBEFORE行トリガー内に割り当てることができますが、(AFTER行トリガーが起動される前にトリガーを実行する文が有効となるため)AFTER行トリガーにnew列値を割り当てることはできません。BEFORE行トリガーによってnew.columnの値が変更されると、同じ文によって起動されるAFTER行トリガーは、BEFORE行トリガーによって割り当てられた変更を参照します。WHEN句のブール式には相関名を使用することもできます。oldおよびnew修飾子をトリガー本体で使用する場合は、修飾子の前にコロン(:)を付ける必要があります。修飾子をWHEN句またはREFERENCINGオプションで使用する場合、コロンは使用できません。通常のSQLおよびCLOB列を持つPL/SQLファンクションを使用して、LOB列を他の列と同様に処理できます。BLOB列を持つDBMS_LOBパッケージをコールできます。OFトリガーの場合は、newおよびold修飾子が、ネストした表の新しい要素および古い要素に対応します。このネストした表の要素に対応する親である行は、parent修飾子を使用してアクセスできます。親相関名は、ネストした表のトリガー内でのみ意味があり有効です。トリガーとの名前の競合の回避(REFERENCINGオプション)行トリガーのトリガー本体にREFERENCINGオプションを指定して、oldまたはnewとネーミングされる相関名または表の重複を避けることができます。このようなことはほとんど発生しないため、このオプションはほとんど使用されません。field1(数値)およびfield2(文字)の列を含むnew表があるとします。TRIGGERの例は、相関名を指定できる表newに対応付けられるトリガーの例です。相関名と表名の重複が避けられています。次のようなデータ構造を設定しないと機能しない例もあります。(:newest.field1);END;REFERENCINGオプションを使用してnew修飾子をnewestに名前を変更し、その後でトリガー本体に使用していることに注意してください。Emp_tab)は、トリガー本体で条件述語のINSERTING、DELETINGおよびUPDATINGを使用して、トリガーを起動する文の種類の確認ができます。トリガー本体のコード内で、トリガーを起動するDML操作の種類に応じて、次のコード・ブロックを実行できます。IF;最初の条件は、トリガーを起動した文がINSERT文の場合にのみTRUEと評価されます。2番目の条件は、トリガーを起動した文がUPDATE文の場合にのみTRUEと評価されます。UPDATEトリガーでは、UPDATING条件述語に列名を指定して、指定した列が更新されているかどうかを判断できます。トリガーが次のように定義されているとします。IF;END;THEN句のコードは、トリガーUPDATE文がSAL列を更新する場合にのみ実行されます。このように、対象の列が変更されていない場合は、トリガーはオーバーヘッドを最小化できます。トリガー本体内のエラー条件および例外トリガー本体の実行中に、事前定義またはユーザー定義のエラー条件または例外が発生すると、トリガーを実行する文のみでなくトリガー本体のすべての影響が(エラーが例外ハンドラによって検出された場合を除き)ロールバックされます。したがって、トリガー本体は例外を発生させることによって、トリガーを実行する文を実行しないで済みます。ユーザー定義例外は、複雑なセキュリティ認可または整合性制約を施行するトリガーによく使用されます。これに対する唯一の例外は、対象イベントがデータベースのSTARTUP、SHUTDOWN、またはログインしているユーザーがSYSTEMのときのLOGINの場合です。このような場合は、トリガー・アクションのみがロールバックされます。オブジェクト表に対するトリガー10gリリース1(10.1)以降、オブジェクト表に対するトリガーでは、OBJECT_VALUE疑似列を使用できます。OBJECT_VALUEは、オブジェクト全体を意味します。これは1つの使用例です。IN仮パラメータのデータ型として、OBJECT_VALUEを指定したPL/SQLファンクションもコールできます。次に、トリガー内でのOBJECT_VALUEの使用例を示します。オブジェクト表tbl内の値に対する更新を追跡するために、次の例では、履歴表であるtbl_historyが作成されます。tblの場合、1〜5までの値がnに挿入されます。トリガーは、DML文によって影響を受ける各行に対して1回実行される行レベルのトリガーです。tblが更新されると、トリガーにより、tbl内のオブジェクトtのold値およびnew値がtbl_historyに書き込まれます。old値およびnew値は、:OLD.OBJECT_VALUEおよび:NEW.OBJECT_VALUEです。表tblの更新が行われます(各n値が1ずつ増加します)。トリガーが動作していることを確認するために、履歴表からの選択内容が、例の終わりに示されます。LOOP;END;/選択結果は、列nの値がすべて1ずつ増加していることを示しています。mの値は0のままです。選択結果は次のとおりです。0トリガーおよびリモート例外処理リモート・サイトにアクセスするトリガーは、ネットワーク・リンクが使用できない場合はリモート例外処理を実行できません。('x');END;トリガーは作成されたときにコンパイルされます。Databaseはリモート・データベースにアクセスする文の妥当性チェックができず、コンパイルは正常に実行されません。前述の例外文の例は、トリガーがコンパイルを完了しないため実行できません。ストアド・プロシージャはコンパイル済の形式で格納されるため、前述の例の回避策は次のようになります。('x');END;この例のトリガーは正常にコンパイルし、ストアド・プロシージャをコールします。このストアド・プロシージャには、リモート・データベースにアクセスするための妥当性チェック済の文がすでにあります。したがって、リンクが使用できないためにリモートINSERT文が失敗すると、例外が捕捉されます。トリガー作成の制限トリガーのコーディングには、標準PL/SQLブロックにはない、いくつかの制約があります。次の項では、トリガーのこのような制約を説明します。トリガーの最大サイズトリガーのサイズは、32KB以下に指定する必要があります。SQL文を含めることができます。INTO...文またはカーソル定義内のSELECT文を指定する必要があります。DDL文はトリガー本体には含めることはできません。トランザクション制御文もトリガーには含めることはできません。ROLLBACK、COMMITおよびSAVEPOINTは使用できません。TABLE文およびALTER...COMPILEを使用できます。注意トリガーによってコールされるプロシージャは、トリガー本体のコンテキスト内で実行されるため、このようなプロシージャが前述のトランザクション制御文を実行することはできません。トリガー内の文では、リモート・スキーマ・オブジェクトを参照できます。ローカル・トリガー内からリモート・プロシージャをコールするときは、特に注意が必要です。トリガーの実行中にタイムスタンプまたはシグネチャの不一致が見つかると、リモート・プロシージャは実行されず、トリガーが無効になります。RAWデータ型には、次の制限があります。RAWデータ型の列にデータを挿入できます。RAW列を参照できます。これらのデータ型の最大長は32000バイトです。RAWデータ型を指定して変数を宣言することはできません。RAW列では、:NEWおよび:PARENTは使用できません。CASCADE制約の影響によって更新される可能性のある表のことです。トリガーを実行する文を発行したセッションは、変更表を問合せまたは変更できません。この制限によって、トリガーは一貫性のないデータは参照しません。ROW句を使用するすべてのトリガーに適用されます。OFトリガー内で変更中のビューは、変更ビューとみなされません。変更表でトリガーが起動されると、ランタイム・エラーが発生し、トリガー本体の処理結果およびトリガーを実行する文がロールバックされ、ユーザーまたはアプリケーションに制御が戻ります。次のトリガーについて検討してみます。employees.');END;次のSQL文が入力されるとします。7499;行が削除されるときに表が変更中であるため、次のエラーが戻されます。ORA-04091:表SCOTT.Emp_tabは変更しています。ROW行を削除すると、このトリガーは文トリガーになり、制限やトリガーの対象にはなりません。変更表を更新する必要がある場合、一時表、PL/SQL表またはパッケージ変数を使用してこれらの制限を回避することもできます。元の表を更新する1つのAFTER行トリガーが変更表エラーとなった場合、かわりに、一時表を更新するAFTER行トリガーおよび一時表からの値を使用して元の表を更新するAFTER文トリガーの2つのトリガーを使用できる場合があります。宣言整合性制約は、行トリガーに関して随時テストされます。サポートされていないため、変更表の制限は、リモート・ノードにアクセスするトリガーには適用されません。これらの制限は、ループバック・データベース・リンクで接続されている同一データベース内の表の間でも施行されません。Netパスを定義して、ローカル表がリモートで表示されます。変更表の制約の緩和この項の前半で説明したように、変更エラーが存在するため、親文が変更する表をトリガーが読込みまたは変更を行うことはできません。Databaseリリース8.1以上では、親表に対して削除を行うと、BEFORE/AFTER文トリガーが1回起動されます。これによって、(行トリガー以外の)トリガーを作成して親表および子表の読込みおよび変更を行うことができます。これによって、ほとんどの外部キー制約アクションはそれらの明白なAFTER行トリガーを経由して実装されるため、制約は自己参照的ではなくなります。更新カスケード、更新セットNULL、更新セット・デフォルト、削除セット・デフォルト、欠落した親の挿入および子件数メンテナンスは、すべて簡単に実装できます。次に、更新カスケードの実装の例を示します。この実装の場合、複数行を更新するときに注意が必要です。表pに値(1)、(2)、(3)を持つ3つの行があり、表fにも値(1)、(2)、(3)を持つ3つの行があるとすると、次の文はpを正常に更新しますが、トリガーがfを更新するときに問題が発生します。この文はpの値(1)から(2)への更新を行い、トリガーはfの値(1)から(2)への更新を行い、fに値(2)の2つの行を残します。次に、文はpの値(2)から(3)への更新を行い、トリガーはfの2つの行の値を両方とも(2)から(3)へ更新します。最後に、文はpの値(3)から(4)への更新を行い、トリガーはfの3つの行すべてを(3)から(4)へ更新します。pとfのデータの関連は失われます。この問題を回避するため、主キーを変更するpの複数行更新を禁止し、既存の主キー値を再利用する必要があります。更新された外部キー値を追跡し、どの行も2回更新されないようにトリガーを変更することで解決することもできます。これが、外部キーの更新に関するこの方法の唯一の問題です。トリガーは、別のトランザクションによってコミットされていない変更済の行を見逃すことはありません。これは、AFTER行トリガーがコールされるまでは、いずれの一致する外部キー行もロックされないことを外部キー制約が保証するためです。システム・トリガーの制限イベントの違いによって、様々なイベント属性関数が使用できます。特定のDDL操作をDDLイベントに対して使用できない場合があります。イベント属性関数は、エラー条件を作成するのではなく、定義されない場合があるため、イベント属性関数を使用する前に、「イベント属性関数」を確認してください。コミットされたトリガーのみが起動されます。すべてのCREATEイベントの後に起動されるトリガーを作成した場合、このトリガーはそのトリガー自身の作成後には起動されません。これは、CREATEイベントが起動された時点では、このトリガーに関する正しい情報はまだコミットされていないためです。次のSQL文を実行するとします。トリガーmy_triggerは、my_triggerの作成後には起動されません。Databaseでは、コミットされていないトリガーは起動されません。外部関数のコールアウト外部関数のコールアウトに関するすべての制限も適用されます。トリガー・ユーザーとは次の文では、トリガーには、トリガーの所有者の名前は戻されますが、表を更新しているユーザーの名前は戻されません。TRIGGERシステム権限および次のいずれかが必要です。TRIGGERシステム権限が必要です。この権限があると、任意のスキーマ内にトリガーを作成し、任意のユーザーの表と対応付けることができます。トリガーを作成するユーザーには、参照するプロシージャ、ファンクションまたはパッケージに対するEXECUTE権限も必要です。TRIGGER権限が必要です。この権限が後になって取り消された場合、トリガーを削除することはできますが、変更することはできません。トリガー本体で参照されるスキーマ・オブジェクトへのオブジェクト権限は、トリガーの所有者に(ロールを介さずに)明示的に付与する必要があります。トリガー本体の文は、トリガーを実行する文を発行するユーザーの権限ドメインではなく、そのトリガーの所有者の権限ドメインから操作します。これは、ストアド・プロシージャの権限モデルと類似しています。トリガーのコンパイルトリガーは、無名PL/SQLブロックに:newおよび:old機能を追加したものと類似していますが、コンパイル方法が異なります。無名PL/SQLブロックは、メモリーにロードされると、常に、コンパイルされます。コンパイルには、次の3段階が必要です。PL/SQL構文がチェックされ、解析ツリーが生成されます。タイプ・チェックおよび解析ツリーに対する追加処理が行われます。pcodeが生成されます。TRIGGER文が入力されたときに完全にコンパイルされ、pcodeはデータ・ディクショナリに格納されます。そのため、トリガーを起動するときに、共有カーソルをオープンしてトリガー・アクションを実行する必要はなくなります。そのかわり、トリガーは直接実行されます。トリガーのコンパイル中にエラーが発生しても、トリガーは作成されます。DML文がこのトリガーを起動すると、そのDML文は失敗します。(ランタイム・トリガー・エラーが発生すると、DML文は必ず失敗します。ERRORS文を使用するか、またはUSER_ERRORSビューからエラーをSELECTすることができます。トリガーの依存関係コンパイル済のトリガーには依存関係があります。このようなトリガーは、トリガー本体からコールされるファンクションまたはストアド・プロシージャのような依存対象となるオブジェクトが修正されると無効になります。依存性の理由で無効になったトリガーは、次に起動された時点で再コンパイルされます。ALL_DEPENDENCIESビューを調べると、トリガーの依存関係がわかります。次の文は、SCOTTスキーマ内のトリガーの依存関係を示します。'TRIGGER';トリガーは他のファンクションまたはパッケージに依存することがあります。トリガー内に指定されているファンクションまたはパッケージが削除されると、トリガーは無効とマークされます。イベントの発生時点で、トリガーの有効性が妥当性チェックされます。ERRORSとマークされ、イベントが失敗します。注意STARTUPイベントに関しては例外が1つあります。STARTUPイベントは、トリガーが失敗しても正常に実行されます。SYSTEMとしてログインした場合は、SHUTDOWNイベントおよびLOGONイベントに関しても例外があります。メッセージのエンキューにはDBMS_AQパッケージが使用されるため、トリガーとキューの間の依存性は維持されません。TRIGGERコマンドを使用します。次の文はPRINT_SALARY_CHANGESトリガーを再コンパイルします。TRIGGERシステム権限が必要です。トリガーの変更ストアド・プロシージャと同様に、トリガーは明示的に変更することはできません。新しい定義と置き換える必要があります。TRIGGER文は、トリガーを再コンパイルするか、使用可能にするかまたは使用禁止にするためにのみ使用します。REPLACEオプションを指定する必要があります。REPLACEオプションを使用することによって、元のトリガーに付与された権限に影響せずに、古いトリガーを新しいトリガーに置き換えることができます。TRIGGER文を再実行できます。TRIGGERシステム権限が必要です。トリガーのデバッグストアド・プロシージャで使用できる機能と同じ機能を使用して、トリガーをデバッグできます。「ストアド・プロシージャのデバッグ」トリガーの使用可能および使用禁止トリガーは、次の2つのモードのどちらかです。使用可能:トリガーを実行する文が入力され、トリガー制限が(存在する場合に)TRUEと評価された場合、使用可能トリガーによってトリガー本体が実行されます。使用禁止:トリガーを実行する文が入力され、トリガー制限が(存在する場合に)TRUEと評価された場合でも、使用禁止トリガーはトリガー本体を実行しません。トリガーの使用可能デフォルトでは、トリガーは、作成時に自動的に使用可能に設定されます。トリガーは後で使用禁止にできます。トリガーを使用禁止にする必要がある作業を終了した後は、トリガーが適切なときに起動されるように、再び使用可能にしておきます。TRIGGER文のENABLEオプションを使用します。INVENTORY表の使用禁止にされたREORDERトリガーを使用可能にするには、次のように入力します。TRIGGERSオプションを使用すると、1つの文で、ある表に定義されているすべてのトリガーを使用可能にできます。INVENTORY表に定義されているすべてのトリガーを使用可能にするには、次のように指定します。次のような場合、一時的にトリガーを使用禁止にできます。大規模なデータ・ロードを実行する必要があり、トリガーを起動せずに迅速に処理する場合データを再ロードする場合デフォルトでは、トリガーは作成時に使用可能に設定されます。TRIGGER文のDISABLEオプションを使用します。INVENTORY表のREORDERトリガーを使用禁止にするには、次のように指定します。TRIGGERSオプションを使用すると、1つの文で、ある表に対応づけられたすべてのトリガーを使用禁止にできます。INVENTORY表に定義されているすべてのトリガーを使用禁止にするには、次のように指定します。TRIGGERS;トリガーに関する情報のリスト次のデータ・ディクショナリ・ビューには、トリガーに関する情報が表示されます。USER_TRIGGERSALL_TRIGGERSDBA_TRIGGERS新しい列BASE_OBJECT_TYPEは、トリガーがDATABASE、SCHEMA、表またはビューのどれに基づくかを示します。基になるオブジェクトが表またはビューでない場合は、古い列TABLE_NAMEがNULLです。ACTION_TYPE列は、トリガーがコール型のトリガーかPL/SQLトリガーかを示します。EVENTが含まれます。TRIGGERING_EVENT列には、システム・イベントおよびDMLイベントがすべて含まれます。Databaseリファレンス』を参照してください。REORDERトリガーを作成する次の文を考えます。次のデータ構造を設定しないと機能しない例もあります。IF;END;次の2つの問合せは、REORDERトリガーに関する情報を戻します。Databaseの情報管理をカスタマイズできます。一般に、トリガーは次の用途に使用します。更新可能な複合ビューの作成システム・イベントの追跡この項では、これらのトリガー・アプリケーションの例を紹介します。これらの例をそのまま使用することはできませんが、トリガーを設計するときの参考にしてください。Databaseの組込み監査機能を補うためによく使用されます。トリガーを作成して、AUDITコマンドによって記録される情報と同様の情報を記録することはできますが、トリガーは、より詳細な監査情報が必要な場合に使用します。トリガーを使用すると、行単位の値に基づく監査が可能です。考えられていることに対して、トリガーは、財務監査機能を提供します。Databaseの監査機能で何が提供されるかを検討します。標準監査オプションによって、すべてのタイプのスキーマ・オブジェクトと構造体に関するDML文とDDL文の監査が可能です。これに比べて、トリガーでは、表に対して入力されたDML文の監査と、SCHEMAまたはDATABASEレベルでのDDL監査ができます。Databaseの監査機能によって自動的、集中的に記録されます。Databaseの標準機能で使用可能になる監査機能は宣言およびメンテナンスが簡単で、エラーが発生しにくくなります。既存の監査オプションの変更を監査して、不当なデータベース・アクティビティを防止できます。SESSION)、レコードを生成できます。トリガーではセッション単位の監査はできません。監査レコードは、トリガーで監査される表が参照されるたびに生成されます。失敗したデータ・アクセスの監査データ・アクセスがエラーとなった場合、データベース監査を実施するように設定できます。自律型トランザクションが使用されないかぎり、トリガーを実行する文がロールバックされると、トリガーによって生成された監査情報もロールバックされます。Database概要』を参照してください。標準データベース監査機能を使用して、接続および切断のみでなく、セッション・アクティビティ(物理I/O、論理I/O、デッドロックなど)も記録できます。トリガーを使用して高度な監査を行うには、通常、AFTERトリガーを使用します。AFTERトリガーを使用すると、トリガーを実行する文が適切な整合性制約に従った後で、監査情報が記録されます。これによって、整合性制約の例外を生成する文に対する無効な監査処理の実行を防止します。AFTER行トリガーとAFTER文トリガーの使い分けは、監査情報に応じて異なります。行トリガーを使用すると、表の行単位の値に基づく監査が可能です。トリガーでは、監査済SQL文を発行するための理由コードの入力をユーザーに要求することもできます。これは、行レベルおよび文レベルの両方の監査状況に有効です。次の例では、Emp_tab表に対する変更を行ベースで監査するトリガーを示します。この例では、更新前に理由コードをグローバル・パッケージ変数に格納する必要があります。トリガーを使用して値ベースの監査を実行する方法、およびパブリック・パッケージ変数を使用する方法を示します。次のデータ構造を設定しないと機能しない例もあります。);END;更新のたびに強制的に理由コードを設定する場合は、理由コードをNULLに設定しなおすこともできます。次の簡単なAFTER文トリガーは、トリガーを実行する文が実行された後で理由コードをNULLに設定します。auditpackage.set_reason(NULL);END;前述のトリガーは、2つとも同じ種類のSQL文によって起動されます。AFTER行トリガーが、トリガーを実行する文によって影響を受ける表の行ごとに1回起動されるのに対して、AFTER文トリガーは、トリガーを実行する文の実行が終了したときに1回のみ起動されます。次に示すトリガーもトリガーを使用して監査を行います。このトリガーは、Emp_tab表に加えられた変更を追跡し、この情報をAUDIT_TABLEとAUDIT_TABLE_VALUESに格納します。次のデータ構造を設定しないと機能しない例もあります。例トリガーおよび宣言整合性制約は、両方ともデータ入力の制限に使用できます。トリガーと整合性制約には大きな違いがあります。宣言整合性制約はデータベースに関する文で、これは常にTRUEです。表内の既存のデータおよび表を操作するすべての文に対して制約が適用されます。第6章「アプリケーション開発におけるデータ整合性のメンテナンス」トリガーは、トランザクションで可能な処理を制約します。トリガーは、トリガーが定義される前にロードされたデータには適用されません。このため、表内のすべてのデータが、対応付けられたトリガーによって確立されたルールに適合するかどうかは確認できません。サポートするルールと同じルールの多くを施行できますが、トリガーは、標準の整合性制約では定義できない複雑なビジネス・ルールを規定するためにのみ使用するようにしてください。トリガーで定義する制約に比べて、次のメリットがあります。一元化された整合性チェック:すべてのデータ・アクセス・ポイントは、各スキーマ・オブジェクトに対応する整合性制約によって定義されたグローバルな一連のルールに準拠する必要があります。宣言方式:標準の整合性制約機能を使用して定義された制約は、トリガーで定義された同等の制約と比較して、より作成しやすくエラーが発生しにくいというメリットがあります。データ整合性のほとんどは、宣言整合性制約によって定義して施行できますが、トリガーは宣言整合性制約では定義できない複雑なビジネス制約の施行に使用できます。トリガーを使用して次を施行できます。DEFAULTの参照アクション親表と子表が分散データベースの異なるノード上にある場合の参照整合性CHECK制約で指定できる式では定義できない複雑なCHECK制約トリガーを使用した参照整合性トリガーを使用して参照整合性を施行できる場合が多々あります。トリガーを使用するのは、実行しているアクションに宣言整合性がサポートされていない場合のみにしてください。トリガーを使用して参照整合性をメンテナンスするときは、親表に主キー(または一意キー)制約を宣言します。同じデータベース内の親表と子表間の参照整合性をトリガーでメンテナンスしている場合は、子表にも外部キーを宣言できますが、外部キーは使用禁止に設定してください。使用禁止にすることによって、対応する主キー制約が(CASCADEオプションを使用して、主キー制約を明示的に削除しないかぎり)削除されなくなります。トリガーを使用して参照整合性をメンテナンスするには、次のようにします。子表にトリガーを1つ定義する必要があります。このトリガーは、外部キーに挿入または更新される値が親キーの値と対応することを保証します。親表には、1つ以上のトリガーを定義する必要があります。NULL)が実行されることを保証します。親表への挿入にアクションは不要です(依存する外部キーはありません)。次の項では、参照整合性の規定に必要なトリガーの例を紹介します。これらの例ではEmp_tab表およびDept_tab表を使用します。UPDATE)が含まれています。この操作は、行を処理するときの同時実行性のメンテナンスに必要です。次のトリガーでは、INSERT文またはUPDATE文が外部キーに影響する前に、対応する値が親キー内に確実に存在するようにします。次の例に含まれる変更表例外によって、このトリガーをUPDATE_SET_DEFAULTトリガーおよびUPDATE_CASCADEトリガーとともに使用できるようになります。このトリガーを単独で使用する場合は、この例外を削除できます。RESTRICT参照アクションを施行します。Dummy_cursor;END;注意このトリガーは、自己参照型の表(主キーまたは一意キーが存在し、さらに外部キーが存在する表)では機能しません。このトリガーでは、トリガーの循環(AがBを起動し、BがAを起動する)は使用できません。NULL参照アクションを施行します。CASCADE参照アクションを施行します。DEFAULTのコードと組み合されます。次のトリガーは、Dept_tab表の部門番号が更新されたときに、その変更がEmp_tab表の依存外部キーに確実に伝播されるようにします。Integritypackage.Updateseq;END;注意このトリガーによってEmp_tab表が更新されるため、Emp_dept_checkトリガーも起動されます(トリガーが使用可能になっている場合)。結果の変更表エラーは、Emp_dept_checkトリガーによって検出されます。エラーの検出を必要とするトリガーは、本番環境で常に正常に動作することを保証するために、慎重にテストする必要があります。例トリガーは、参照整合性以外の整合性ルールも施行できます。次のトリガーは、トリガーを実行する文の実行を許可する前に、複雑なチェックを実行します。次のデータ構造を設定しないと機能しない例もあります。例トリガーは、一般に、表データに対する複雑なセキュリティ認可の施行によく使用されます。Databaseが提供するデータベース・セキュリティ機能では定義できない複雑なセキュリティ認可の施行にのみ使用します。トリガーを使用して、週末、休日および休業日には、Emp_tab表の給与データを更新できないようにすることができます。複雑なセキュリティ認可の施行にトリガーを使用する場合は、BEFORE文トリガーを使用すると最も効果的です。BEFORE文トリガーを使用すると、次のようなメリットがあります。トリガーを実行する文の実行が許可される前に、セキュリティ・チェックが実行されるため、不当な文による無駄な作業をせずに済みます。セキュリティ・チェックは、トリガーを実行する文に影響される行ごとではなく、トリガーを実行する文に対して1回のみ実施されます。次の例は、セキュリティを施行するために使用するトリガーを示します。次のデータ構造を設定しないと機能しない例もあります。Databaseセキュリティ・ガイド』を参照してください。特定のイベントに続いてデータベースに透過的な変更を実行する場合、トリガーは非常に効果的です。REORDERトリガーの例では、一定の条件が満たされると、必要に応じて部品を再注文するトリガーを示します。(トリガーを実行する文が入力され、PARTS_ON_HAND値がREORDER_POINT値より小さい場合です。例トリガーは、INSERT文またはUPDATE文に指定される値に基づいて、列の値を自動的に取得できます。この種のトリガーは、同一行上の別の列の値に依存する特定の列に値を埋め込む場合に便利です。この種の操作を実行するには、BEFORE行トリガーが必要ですが、これは次の理由によります。トリガーを実行する文で導出値を使用できるようにするには、INSERTまたはUPDATEが発生する前に依存値を取得する必要があります。トリガーを実行するINSERT文またはUPDATE文によって影響される行ごとに、トリガーを起動する必要があります。次の例では、行が挿入または更新されるたびに、表の新しい列値を導出するトリガーの使用方法を示します。次のデータ構造を設定しないと機能しない例もあります。例ビューは、表データに対して論理ウィンドウを提供する優れた手段です。問合せが複雑になると、ビューに対するDMLから基礎となる表に対するDMLへの変換を、システムが暗黙的には実行できなくなります。OFトリガーが有効です。このトリガーは、ビューに対して定義することができ、実際のDMLのかわりに起動されます。書籍が書名の順に配置されているライブラリ・システムを考えてみます。このライブラリは、書籍型オブジェクトのコレクションで構成されています。次の例はこのスキーマについて説明したものです。Book_t;関係スキーマに次の表があるとします。MNこのライブラリは、library_table(section)で構成されています。参照先GeographyClassicこれらの表に対して複合ビューを定義し、セクションおよび各セクション内の書籍集合を示すライブラリの論理ビューを作成することができます。OFトリガーを定義し、このビューを更新可能にします。LOOP;END;/これでlibrary_viewは更新可能ビューになり、このビューに対するすべてのINSERTは、自動的に起動されるトリガーによって処理されます。'Y');同様に、ネストした表であるbooklistに対してトリガーを定義して、ネストした表の要素の変更を処理することもできます。例システム・トリガーは、アプリケーション・コンテキストの設定に使用できます。アプリケーション・コンテキストは比較的新しい機能であり、ファイングレイン・アクセス・コントロールを実装する機能が向上します。アプリケーション・コンテキストは保護されたセッション・キャッシュで、セッション固有の属性の格納に使用できます。次に示す例では、set_ctxプロシージャがユーザー・プロファイルに基づいてアプリケーション・コンテキストを設定します。setexpensectxトリガーは、コンテキストがユーザーごとに確実に設定されるようにします。Secdemo.Exprep_etx.Set_otxトリガーを介したシステム・イベントに対する応答システム・イベントを発行することによって、アプリケーションは、他のアプリケーションからのメッセージにサブスクライブするのと同じ方法で、データベース・イベントにサブスクライブできます。システム・イベント発行フレームワークには、次の機能が含まれています。パブリッシュ/サブスクライブのためのインフラストラクチャ。データベースがイベントのアクティブな発行者になります。サーバーへのデータ・カートリッジの統合。システム・イベントを発行して、サーバー内の状態の変更をカートリッジに通知することができます。サーバーへのファイングレイン・アクセス・コントロールの統合。トリガーを作成すると、イベント発生時に実行するプロシージャを指定できます。DMLイベントは表でサポートされ、システム・イベントは、データベースおよびスキーマでサポートされます。TRIGGER文を使用してトリガーを使用可能および使用禁止にすると、通知をオンおよびオフにすることができます。この機能は、アドバンスト・キューイング・エンジンに統合されています。パブリッシュ/サブスクライブ・アプリケーションは、DBMS_AQ.ENQUEUE()プロシージャを使用し、他のアプリケーション(カートリッジなど)は、コールアウトを使用します。Streamsアドバンスト・キューイング・ユーザーズ・ガイドおよびリファレンス』を参照してください。トリガーを介したイベントの発行方法データベースによってイベントが検出されると、トリガー・メカニズムがトリガー内に指定されているアクションを実行します。このアクションの一部として、DBMS_AQパッケージを使用してイベントをキューに発行でき、キューによって、サブスクライバが通知を取得します。注意この方法で検出できるのは、システム定義のデータベース・イベントのみです。独自のイベント条件は定義できません。イベントが発生すると、そのイベントに対して使用可能なすべてのトリガーがデータベース上で起動されます。これには次の例外があります。トリガーがトリガー・イベントのターゲットである場合、このトリガーは起動されません。すべてのDROPイベントのトリガーは、削除される場合は起動されません。トリガーが変更されているが、イベントの起動と同じトランザクション内でコミットされていない場合、このトリガーは起動されません。システム・トリガー内の再帰DDLがトリガーを変更する場合がありますが、これによって変更されたトリガーが同じトランザクション内で起動されなくなります。オブジェクトに対して複数のトリガーを作成できます。イベントが複数のトリガーを起動する場合、起動順序は定義されないため、特定の順序内で起動されるトリガーに依存しないでください。発行コンテキストイベントが発行されるときは、パラメータ・リストに指定されている特定の実行時コンテキストおよび属性がコールアウト・プロシージャに渡されます。イベント属性関数と呼ばれる一連の関数が提供されています。関連項目イベント固有の属性の詳細は、「イベント属性関数」を参照してください。サポートされているシステム・イベントごとに、イベント固有の属性が指定され、事前定義されています。パラメータ・リストには、他の単純な式とともにこの属性のいずれかを選択できます。コールアウトの場合、これらはIN引数として渡されます。発行コールアウト関数からの戻り状態は、すべてのイベントに関して無視されます。SHUTDOWNイベントの場合、データベースは戻り状態に関しては何も実行できません。戻り状態の詳細は、「データベース・イベントのリスト」を参照してください。実行モデルトリガーは、従来からトリガーの定義者として実行されてきました。イベントのトリガー・アクションは、アクションの定義者として(コールアウト内のパッケージまたはファンクションの定義者、またはキュー内のトリガーの所有者として)実行されます。トリガーの所有者には、基になるキュー、パッケージまたはプロシージャに対するEXECUTE権限が必要なため、この動作には一貫性があります。イベント属性関数データベースでトリガーが起動されると、トリガーを起動したイベントの属性を検索できます。ファンクション・コールを使用して各属性を検索できます。表9-2では、システムで定義されたイベント属性について説明します。注意これらの属性を使用可能にするには、まず、CATPROC.SQLスクリプトを実行する必要があります。トリガー・ディクショナリ・オブジェクトは、発行されるイベントに関するメタデータおよびそれに対応する属性をメンテナンスします。以前のリリースでは、これらのファンクションはSYSパッケージを介してアクセスされていました。名前がora_で始まるこれらのパブリック・シノニムを使用することをお薦めします。ora_client_ip_addressVARCHAR2基礎となるプロトコルがTCP/IPのとき、LOGONイベントでクライアントのIPアドレスを戻します。IF;END;ora_database_nameVARCHAR2(50)データベース名を戻します。ora_database_name;END;ora_des_encrypted_passwordVARCHAR2作成または変更されるユーザーのDES暗号化パスワードを戻します。IF;ora_dict_obj_nameVARCHAR(30)DDL操作が発生したディクショナリ・オブジェクトの名前を戻します。ora_name_list_t)BINARY_INTEGERこのイベントで変更されるオブジェクトのオブジェクト名のリストを戻します。IF;ora_dict_obj_ownerVARCHAR(30)DDL操作が発生したディクショナリ・オブジェクトの所有者を戻します。ora_name_list_t)BINARY_INTEGERこのイベントで変更されるオブジェクトのオブジェクト所有者のリストを戻します。IF;ora_dict_obj_typeVARCHAR(20)DDL操作が発生したディクショナリ・オブジェクトのタイプを戻します。ora_name_list_t)BINARY_INTEGEROUTパラメータで権限付与イベントの権限受領者を戻し、戻り値で権限受領者の数を戻します。IF;ora_instance_numNUMBERインスタンス番号を戻します。VARCHAR2)BOOLEAN指定された列が変更された場合、trueを戻します。IF;ora_is_creating_nested_tableBOOLEAN現行のイベントがネストした表を作成しているときに、trueを戻します。VARCHAR2)BOOLEAN指定された列が削除された場合、trueを戻します。IF;ora_is_servererrorBOOLEAN指定されたエラーがエラー・スタック上にある場合はtrue、ない場合はfalseを戻します。IF;ora_login_userVARCHAR2(30)ログイン・ユーザー名を戻します。OFトリガーでは、PARTITION句を挿入できるSQLテキスト内の位置を戻します。ora_name_list_t)BINARY_INTEGER権限受領者によって付与された権限のリストまたは取消し側から取り消された権限のリストを、OUTパラメータで戻します。戻り値として権限の数を戻します。ora_name_list_t)BINARY_INTEGEROUTパラメータで取消しイベントの取消し側を戻します。戻り値として取消し側の数を戻します。ora_revokee(user_list);ora_server_errorNUMBER(スタックの一番上を1として)位置を指定すると、エラー・スタック上のその位置のエラー番号を戻します。ora_server_error(1));ora_server_error_depthBINARY_INTEGERエラー・スタック上のエラー・メッセージの合計数を戻します。binary_integer)VARCHAR2(スタックの一番上を1として)位置を指定すると、エラー・スタック上のその位置のエラー・メッセージを戻します。binary_integer)BINARY_INTEGER(スタックの一番上を1として)位置を指定すると、「%s」などの書式を使用してエラー・メッセージ内で置き換えられた文字列数を戻します。binary_integer)VARCHAR2(スタックの一番上を1として)位置およびパラメータ番号を指定すると、「%s」、「%d」などに一致するエラー・メッセージ内の代入値を戻します。ora_name_list_t)BINARY_INTEGEROUTパラメータ内のトリガーを実行する文のSQLテキストを戻します。この文が長い場合、複数のPL/SQL表要素に分割されます。ファンクションの戻り値は、PL/SQL表内の要素数を示します。v_stmt);ora_syseventVARCHAR2(20)トリガーを起動するシステム・イベントを戻します。イベント名は、構文にある名前と同じです。(ora_sysevent);ora_with_grant_optionBOOLEAN権限オプションとともに権限が付与された場合、trueを戻します。VARCHAR2)BOOLEANエラーが領域不足状態に関連する場合trueを戻し、エラーの原因となったオブジェクトに関する情報をOUTパラメータで戻します。IF;データベース・イベントのリストこの項では、重要なシステム・イベントおよびクライアント・イベントについて説明します。システム・イベントシステム・イベントは、個々の表または行ではなく、インスタンスまたはスキーマ全体に関係します。起動イベントおよび停止イベントに対して作成されたトリガーは、データベース・インスタンスに関連付けられる必要があります。エラー・イベントおよび一時停止イベントに対して作成されたトリガーは、データベース・インスタンスまたは特定のスキーマのいずれかへの関連付けが可能です。表9-3に、システム・マネージャ・イベントのリストを示します。制限事項トランザクション属性関数STARTUPデータベースのオープン時なしトリガーではデータベース処理はできません。戻り状態は無視されます。トリガーの起動後、別のトランザクションを開始してこれをコミットします。ora_syseventora_login_userora_instance_numora_database_nameSHUTDOWNサーバーがインスタンス停止を開始する直前これによって、カートリッジを完全に停止できます。インスタンスの異常停止の場合は、このイベントは起動されない場合があります。なしトリガーではデータベース処理はできません。戻り状態は無視されます。トリガーの起動後、別のトランザクションを開始してこれをコミットします。ora_syseventora_login_userora_instance_numora_database_nameDB_ROLE_CHANGEロール変更後、初めてのデータベースのオープン時なし戻り状態は無視されます。トリガーの起動後、別のトランザクションを開始してこれをコミットします。ora_syseventora_login_userora_instance_numora_database_nameSERVERERRORenoエラーの発生時条件が指定されない場合、このイベントは任意のエラーが発生したときに起動します。ORA-1034、ORA-1403、ORA-1422、ORA-1423およびORA-4030の場合、トリガーは起動されません。本当のエラーでないか、または問題が深刻で処理を続行できないためです。ORA-18およびORA-20の場合もトリガーは起動されません。プロセスで、データベースに接続してエラーを記録することができないためです。enoエラーに依存します。戻り状態は無視されます。トリガーの起動後、別のトランザクションを開始してこれをコミットします。ora_syseventora_login_userora_instance_numora_database_nameora_server_errorora_is_servererrorspace_error_infoクライアント・イベントクライアント・イベントは、ユーザーのログイン/ログオフ、DMLおよびDDLの操作に関係するイベントです。LOGONイベントおよびLOGOFFイベントによって、UIDおよびUSERに単純な条件を使用できます。他のすべてのイベントによって、UIDやUSERのような関数のみでなく、オブジェクトの型および名前に単純な条件を使用できます。LOGONイベントは、トリガーの起動後、別のトランザクションを開始してこれをコミットします。他のすべてのイベントは、既存のユーザー・トランザクションでトリガーを起動します。LOGONイベントおよびLOGOFFイベントは、すべてのオブジェクトを操作できます。他のすべてのイベントでは、対応するトリガーは、そのイベントを生成させるオブジェクト上でDROPやALTERなどのDDL操作を実行できません。これらのトリガーで使用できるDDLは、表の変更、作成または削除、トリガーの作成および処理のコンパイルです。TRIGGERなど)の対象になる場合、このトリガーを、後で同じトランザクション中に起動することはできません。表9-4に、クライアント・イベントのリストを示します。DATABASEおよびDDLに対しては起動されません。SUSPEND領域不足状態のためSQL文が一時停止された後。トリガーは、文が再開されるようにこの状態を修正する必要があります。