CREATE TRIGGER

CREATE TRIGGER ステートメントは、現行サーバーでトリガーを定義します。

呼び出し

このステートメントは、アプリケーション・プログラムに組み込むことができ、また対話式に呼び出すこともできます。 これは、動的に準備できる実行可能ステートメントです。

権限

このステートメントの権限 ID が保持する特権には、少なくとも以下の 1 つ が含まれていなければなりません。

このステートメントの権限 ID が保持する特権には、少なくとも以下の 1 つ が含まれていなければなりません。

  • 以下のそれぞれが必要です。
    • トリガーが定義される表またはビューの ALTER 特権、
    • トリガーが定義される表またはビューの SELECT 特権、
    • トリガー・アクション での 検索条件 で参照された表またはビューの SELECT 特権、
    • BEFORE UPDATE トリガーに NEW 相関変数を変更する SET ステートメントが含まれている場合、 トリガーが定義される表の UPDATE 特権、
    • トリガー SQL ステートメント の実行に必要な特権、
    • トリガーが定義される表またはビューが入っているライブラリーに対する *EXECUTE システム権限
  • データベース管理者権限

固有に更新できないビューに INSTEAD OF トリガーが追加される場合、*OBJMGT システム権限もビュー上に必要になります。

さらに、このステートメントの権限 ID が保持する特権には、少な くとも以下の 1 つが含まれていなければなりません。

  • 次のシステム権限
    • 物理ファイル・トリガー追加 (ADDPFTRG) コマンドに対する *USE
    • プログラム作成 (CRTPGM) コマンドに対する *USE
  • データベース管理者権限
SECURED 属性が 指定されるか、または、トリガーがセキュアであり OR REPLACE が指定される場合は、次のとおりです。
  • このステートメントの許可 ID には、セキュリティー管理者権限 がなければなりません。 管理権限を参照してください。

SQL 名が指定され、該当のトリガーが作成されるライブラリーの名前と同じ 名前のユーザー・プロファイルが存在し、しかもその名前がステートメント の権限 ID と異なっている場合、ステートメントの権限 ID が保持す る特権には、少なくとも次の 1 つが含まれていなければなりません。

  • *ALLOBJ および *SECADM 特殊権限
  • データベース管理者権限

既存のトリガーに置き換えるには、ステートメントの権限 ID が保持する特権に、次のうち少なくともいずれか 1 つを含める必要があります。

  • 次のシステム権限
    • トリガー・プログラム・オブジェクトに対する *OBJMGT システム権限
    • このトリガーを削除するために必要な全権限
  • データベース管理者権限

SQL 特権に対応するシステム権限については、『表またはビューへの権限を検査する際の対応するシステム権限』を参照してください。

構文

構文図を読む構文図をスキップする
>>-CREATE--+------------+--TRIGGER--trigger-name---------------->
           '-OR REPLACE-'                          

>--+-trigger-definition-----------------+----------------------><
   '-WRAPPED--obfuscated-statement-text-'   

構文図を読む構文図をスキップする
trigger-definition

     .-NO CASCADE-.             
|--+-+------------+--BEFORE-+----------------------------------->
   +-AFTER------------------+   
   '-INSTEAD OF-------------'   

>--| trigger-event |--ON--+-table-name-+------------------------>
                          '-view-name--'   

>--+------------------------------------------------------------------+-->
   |              .-------------------------------------------------. |   
   |              V        .-ROW-.  .-AS-.                      (1) | |   
   '-REFERENCING----+-OLD--+-----+--+----+--correlation-name--+-----+-'   
                    |      .-ROW-.  .-AS-.                    |           
                    +-NEW--+-----+--+----+--correlation-name--+           
                    |                .-AS-.                   |           
                    +-+-OLD TABLE-+--+----+--table-identifier-+           
                    | '-OLD_TABLE-'                           |           
                    |                .-AS-.                   |           
                    '-+-NEW TABLE-+--+----+--table-identifier-'           
                      '-NEW_TABLE-'                                       

   .-FOR EACH STATEMENT-.  .-MODE DB2SQL-.               
>--+--------------------+--+-------------+--トリガー・アクション----------|
   '-FOR EACH ROW-------'  '-MODE DB2ROW-'               

注:
  1. 同じ文節を複数回指定することはできません。
構文図を読む構文図をスキップする
trigger-event

   .-OR------------------------------------------.   
   V                                             |   
|----+-INSERT----------------------------------+-+--------------|
     +-DELETE----------------------------------+     
     |                                     (1) |     
     '-UPDATE--+-------------------------+-----'     
               |     .-,---------------. |           
               |     V                 | |           
               '-OF------column-name---+-'           

注:
  1. trigger-event オプションは 1 回だけ指定 できます。
構文図を読む構文図をスキップする
triggered-action

|--+-------------+--+----------------------+--+------------------------------+-->
   '-option-list-'  '-SET OPTION-statement-'  '-WHEN--(--search-condition--)-'   

>----SQL-trigger-body-------------------------------------------|

option-list

|--+---------------------------------------------------------------+-->
   |                               .-DEFAULT---------------------. |   
   '-CONCURRENT ACCESS RESOLUTION--+-+-USE CURRENTLY COMMITTED-+-+-'   
                                   | '-U-----------------------' |     
                                   '-+-WAIT FOR OUTCOME-+--------'     
                                     '-W----------------'              

   .-NOT SECURED-.  .-ENABLE--.   
>--+-------------+--+---------+--------------------------------->
   '-SECURED-----'  '-DISABLE-'   

                                           (1)   
>--+-------------------------------------+----------------------|
   '-PROGRAM NAME--external-program-name-'       

注:
  1. オプションは任意の順序で指定できます。 同じ文節を複数回指定することはできません。
構文図を読む構文図をスキップする
SQL-trigger-body

|--+-SQL-control-statement--------------------------+-----------|
   +-fullselect-------------------------------------+   
   +-ALLOCATE CURSOR-statement----------------------+   
   +-ALLOCATE DESCRIPTOR-statement------------------+   
   +-ALTER FUNCTION-statement-----------------------+   
   +-ALTER MASK-statement---------------------------+   
   +-ALTER PERMISSION-statement---------------------+   
   +-ALTER PROCEDURE-statement----------------------+   
   +-ALTER SEQUENCE-statement-----------------------+   
   +-ALTER TABLE-statement--------------------------+   
   +-ASSOCIATE LOCATORS-statement-------------------+   
   +-COMMENT statement------------------------------+   
   +-CREATE ALIAS-statement-------------------------+   
   +-CREATE FUNCTION (external scalar)-statement----+   
   +-CREATE FUNCTION (external table)-statement-----+   
   +-CREATE INDEX-statement-------------------------+   
   +-CREATE MASK-statement--------------------------+   
   +-CREATE PERMISSION-statement--------------------+   
   +-CREATE PROCEDURE (external)-statement----------+   
   +-CREATE SCHEMA-statement------------------------+   
   +-CREATE SEQUENCE-statement----------------------+   
   +-CREATE TABLE-statement-------------------------+   
   +-CREATE TYPE-statement--------------------------+   
   +-CREATE VIEW-statement--------------------------+   
   +-DEALLOCATE DESCRIPTOR-statement----------------+   
   +-DECLARE declared temporary table-statement-----+   
   +-DELETE-statement-------------------------------+   
   +-DESCRIBE-statement-----------------------------+   
   +-DESCRIBE CURSOR-statement----------------------+   
   +-DESCRIBE INPUT-statement-----------------------+   
   +-DESCRIBE PROCEDURE-statement-------------------+   
   +-DESCRIBE TABLE-statement-----------------------+   
   +-DROP-statement---------------------------------+   
   +-EXECUTE IMMEDIATE-statement--------------------+   
   +-GET DESCRIPTOR-statement-----------------------+   
   +-GRANT-statement--------------------------------+   
   +-INSERT-statement-------------------------------+   
   +-LABEL-statement--------------------------------+   
   +-LOCK TABLE-statement---------------------------+   
   +-MERGE-statement--------------------------------+   
   +-REFRESH TABLE-statement------------------------+   
   +-RELEASE-statement------------------------------+   
   +-RELEASE SAVEPOINT-statement--------------------+   
   +-RENAME-statement-------------------------------+   
   +-REVOKE-statement-------------------------------+   
   +-SAVEPOINT-statement----------------------------+   
   +-SELECT INTO-statement--------------------------+   
   +-SET CURRENT DEBUG MODE-statement---------------+   
   +-SET CURRENT DECFLOAT ROUNDING MODE-statement---+   
   +-SET CURRENT DEGREE-statement-------------------+   
   +-SET CURRENT IMPLICIT XMLPARSE OPTION-statement-+   
   +-SET CURRENT TEMPORAL SYSTEM_TIME-statement-----+   
   +-SET DESCRIPTOR-statement-----------------------+   
   +-SET ENCRYPTION PASSWORD-statement--------------+   
   +-SET PATH-statement-----------------------------+   
   +-SET SCHEMA-statement---------------------------+   
   +-SET TRANSACTION-statement----------------------+   
   +-SET transition-variable-statement--------------+   
   +-TRANSFER OWNERSHIP-statement-------------------+   
   +-TRUNCATE-statement-----------------------------+   
   +-UPDATE-statement-------------------------------+   
   '-VALUES INTO-statement--------------------------'   

説明

OR REPLACE
現行サーバーにこのトリガーの定義が存在する場合に、その定義を置き換える、という動作を指定します。実際には、カタログで既存の定義を削除してから新しい定義に置き換える、という動作になりますが、例外として、このトリガーに対して与えられていた特権は影響を受けません。現行サーバーにこのトリガーの定義が存在しなければ、このオプションは無視されます。
trigger-name

トリガーの名前を指定します。暗黙的または明示的修飾子も含め、この名前は、現行サーバーに既に存在 しているトリガーと同じ名前にすることはできません。QTEMP は、トリガー名 スキーマ修飾子として 使用することはできません。

SQL 名が指定されている場合、トリガーは、暗黙的または明示的修飾子で指定して いるスキーマ内に作成されます。

システム名が指定されている場合、トリガーは、修飾子で指定し ているスキーマ内に作成されます。修飾されていない場合、トリガーは、対象表と同じスキーマ内に作成されます。

トリガー名が有効なシステム名でない場合、または同じ名前のプログラムが 既に存在する場合、データベース・マネージャーはシステム名を生成します。名前の生成に関する規則については、表名の生成の規則を参照してください。

NO CASCADE
NO CASCADE は、他のプロダクトとの互換性を保持するた めに許可されており、DB2® for i では無視されます。
BEFORE
トリガーが トリガーであることを指定します。データベース・マネージャーは、対象表に対する挿入、削除、または更新操作による変更を適 用する前に、トリガー・アクション を実行します。前トリガーのトリガー・アクション には更新を含めることができないので、このト リガー・アクション は別のトリガーを起動しないことも指定します。

view-name を指定する場合は、BEFORE を指定しないでください。FOR EACH STATEMENT は、BEFORE トリガーには指定してはいけません。

AFTER
トリガーが トリガーであることを指定します。データベース・マネージャーは、対象表に対する挿入、削除、または更新操作による変更を適 用後に、トリガー・アクション を実行します。view-name を指定する場合は、AFTER を指定しないでください。
INSTEAD OF
トリガーが代用トリガーであることを指定します。対象ビューに対するアクションは、関連付けられたトリガー・アクションに置き換えられます。 対象ビューに対する操作の種類ごとに、INSTEAD OF トリガーを 1 つのみ使用できます。 データベース・マネージャーは、対象ビューに対する挿入、削除、更新の操作の代わりに、トリガー・アクション を実行します。

table-name を指定する場合は、INSTEAD OF を指定しないでください。INSTEAD OF トリガーの場合は、WHEN 文節を指定してはいけません。 FOR EACH STATEMENT は、INSTEAD OF トリガーには指定してはいけません。

trigger-event
これを指定すると、サブジェクト表またはビューにいずれかのイベントが適用される場合には必ず、このトリガーに関連するトリガー・アクションが実行されます。 任意の組み合わせのイベントを指定できますが、各イベント (INSERT、DELETE、UPDATE) は 1 回しか指定できません。
INSERT
サブジェクト表で挿入操作があった場合には必ず このトリガーに関連付けられたトリガー・アクション を実行することを指定します。

変更の始まりBEFORE INSERT トリガーは、履歴表に追加できません。変更の終わり

DELETE
サブジェクト表で削除操作があった場合には必ず このトリガーに関連付けられたトリガー・アクション を実行することを指定します。

DELETE トリガーは、ON DELETE CASCADE 参照制約を含む 表には追加できません。

UPDATE
サブジェクト表で更新操作があった場合には必ず このトリガーに関連付けられたトリガー・アクション を実行することを指定します。

UPDATE トリガー・イベントは、ON DELETE SET NULL または ON DELETE SET DEFAULT 参照制約を含む表には追加できません。

変更の始まりBEFORE UPDATE トリガーは、履歴表に追加できません。変更の終わり

明示的な列名 リストが指定されていない場合、後 で ALTER TABLE ステートメントによって追加される列も含めて、対象表の列 に対する更新操作はすべてトリガー・アクション を起動します。

OF column-name,...
指定する各列名 は、対象表の列でなければなら ず、リストには一度しか表示できません。リストされた列に対する更新操作はすべてト リガー・アクション を起動します。この文節は INSTEAD OF トリガーには指定できません。
ON 表名
BEFORE または AFTER トリガー定義の対象表を識別します。この名前は、現行サーバー上に存在する基本表を示すものでなければならず、カタログ表、QTEMP 内の表、または宣言済み一時表を示すものであってはなりません。
ON ビュー名
INSTEAD OF トリガー定義の対象ビューを識別します。名前は、現行サーバー上 に存在するビューを示すものでなければならず、カタログ・ビューまたは QTEMP 内のビューを示すものであってはなりません。名前は、WITH CHECK OPTION を使用して定義されたビュー、または WITH CHECK OPTION ビューとして定義されているビューを、直接または間接的に示すものであってはなりません。
REFERENCING
遷移表の相関名と遷移表の表名を指定します。相関名 は、トリガー SQL 操作の影響を受 ける行セット内の特定行を識別します。表 ID は、影響を受ける行セット全体 を識別します。
次のように相関名 を指定して列を修飾することに より、トリガー SQL 操作の影響を受ける各行が、トリ ガー・アクション に対して使用可能になります。
OLD ROW AS 相関名
トリガー SQL 操作の前の行の値を識別する相関名を指定します。トリガー・イベント が挿入の場合、OLD ROW の各列の値は NULL 値です。
NEW ROW AS 相関名
トリガー SQL 操作と既に実行された前トリガー内の SET ステートメントによって変更された行の値を識別する相関名を指定します。トリガー・イベント が削除の場合、NEW ROW の各列の値は NULL 値です。
次のように一時表名を指定することにより、トリガー SQL 操作によって影響 を受ける行セット全体が、トリガー・アクション に対して使用可能になります。
OLD TABLE AS 表 ID
トリガー SQL 操作の前の、影響を受ける行セット全体の値を識別す る一時表の名前を指定します。現行トリガーが、あるトリガーの SQL トリガー本体 内のステートメントによって起 動された場合、OLD TABLE には、そのトリガーによって影響を受けた行も含ま れます。トリガー・イベント が挿入の場合、この一時表は空です。
NEW TABLE AS 表 ID
トリガー SQL 操作とすでに実行された前トリガー内の SET ス テートメントによって変更された、影響を受ける行セット全体の状態を識別 する一時表の名前を指定します。トリガー・イベント が削除の場合、この一時表は空です。

1 つのトリガーには、相関名 として、 1 つの OLD と 1 つの NEW だけしか指定できません。 1 つのトリガーには、 表 ID として 1 つの OLD_TABLE と 1 つの NEW_TABLE しか指定できません。 相関名 および 表 ID のすべては相互に固有でなければなりません。

OLD 相関名 および OLD_TABLE 表 ID は、トリガー・イベントが削除操作または更新操作の場合のみ設定されます。削除操作の場合、OLD correlation-name は削除される行の列の値を取り込み、OLD_TABLE table-identifier は削除される行のセットにある値を取り込みます。UPDATE 操作の場合、OLD 相関名 は、 その UPDATE 操作の前の時点での行の列の値を取り込み、 OLD_TABLE 表 ID は、更新された行のセットの値を取り込みます。

NEW ROW 相関名 および NEW TABLE 表 ID は、トリガー・イベントが INSERT 操作または UPDATE 操作 の場合のみ設定されます。どちらの操作の場合も、NEW ROW 相関名 は、挿入または更新された行内の列の値を取り込み、NEW TABLE 表 ID は、挿入または更新された行セット内の 値を取り込みます。前トリガーの場合、更新された行の値には、前トリガー のトリガー・アクション 内の SET ステートメントからの変更が含まれます。

OLD ROW および NEW ROW 相関名 変数は、AFTER トリガーまたは INSTEAD OF トリガー内では変更できません。

下表は、相関変数と遷移表の可能な組み合わせを要約しています。

細分性 : FOR EACH ROW

MODE 起動時 トリガー操作 許される相関変数 許される遷移表
DB2ROW BEFORE DELETE OLD NONE
INSERT NEW
UPDATE OLD, NEW
AFTER または INSTEAD OF DELETE OLD
INSERT NEW
UPDATE OLD, NEW
DB2SQL BEFORE DELETE OLD
INSERT NEW
UPDATE OLD, NEW
AFTER または INSTEAD OF DELETE OLD OLD TABLE
INSERT NEW NEW TABLE
UPDATE OLD, NEW OLD TABLE, NEW TABLE

細分性 : FOR EACH STATEMENT

MODE 起動時 トリガー操作 許される相関変数 許される遷移表
DB2SQL AFTER または INSTEAD OF DELETE NONE OLD TABLE
INSERT NEW TABLE
UPDATE OLD TABLE, NEW TABLE

文字データ・タイプの遷移変数は、対象表の列の CCSID を継承します。 トリガー・アクション の実行時に、遷移変数は変数のように扱われます。 したがって、文字変換が行われる可能性があります。

一時遷移表は、読み取り専用です。これは変更できません。

それぞれの correlation-name、およびそれぞれの table-identifier の有効範囲は、トリガー定義全体です。

FOR EACH ROW
データベース・マネージャーは、トリガー操作が変更する対象表の各行ごとに トリガー・アクション を実行することを指定しま す。そのトリガー操作がどの行も変更しない場合に は、トリガー・アクション は実行されません。
FOR EACH STATEMENT
データベース・マネージャーは、トリガー操作につき一度だけ、 トリガー・アクション を実行することを指定します。 そのトリガー操作がどの行も変更または削除しない場合でも、トリガー・アクションは一度実行します。

FOR EACH STATEMENT は、BEFORE トリガーに対しては指定できません。

FOR EACH STATEMENT は、MODE DB2ROW トリガーに対しては指定できません。

MODE DB2SQL
MODE DB2SQL は AFTER トリガーに対して有効です。MODE DB2SQL AFTER トリガーは、すべての行操作が完了した後で起動されます。

REFERENCING 節 が指定されておらず、トリガー表が SQL-trigger-body 内で参照されていない場合のみ、MODE DB2SQL は BEFORE トリガーに対して 有効です。MODE DB2SQL BEFORE トリガーは、各行の操作時に起動されます。

MODE DB2ROW
MODE DB2ROW トリガーは、各行の操作時に起動されます。

MODE DB2ROW は、BEFORE と AFTER 起動時の両方に有効です。

CONCURRENT ACCESS RESOLUTION
データベース・マネージャーが更新プロセスの過程にあるデータを待つかどうかを指定します。DEFAULT がデフォルトです。
DEFAULT
このトリガーに関する並行アクセスの解決方法を明示的に設定しないことを指定します。このトリガー・プログラムの呼び出し時に有効だった値が使用されます。
WAIT FOR OUTCOME
データベース・マネージャーが更新プロセスの過程にあるデータのコミットまたはロールバックを待つ、という動作を指定します。
USE CURRENTLY COMMITTED
データベース・マネージャーが更新プロセスの過程にあるデータを検出したときに現時点でのコミット済みバージョンのデータを使用する、という動作を指定します。
読み取りトランザクションと削除/更新トランザクションの間でロックの競合が発生した場合に、この文節の適用対象になるのは、分離レベル CS のスキャンです (CS KEEP LOCKS のスキャンは対象になりません)。
SECURED または NOT SECURED
トリガーが行アクセス制御と列アクセス制御においてセキュアであると見なされるかどうかを指定します。NOT SECURED がデフォルトです。
SECURED
トリガーが行アクセス制御と列アクセス制御においてセキュアであると見なされることを指定します。
トリガーのサブジェクト表が行アクセス制御または列アクセス制御を使用している 場合、そのトリガーには SECURED を指定する必要があります。また、トリガーがビューに対して作成され、 そのビュー定義内の 1 つ以上の基礎表が行アクセス制御または列アクセス制御を 使用している場合も、そのトリガーに SECURED を指定する必要があります。
NOT SECURED
トリガーが行アクセス制御と列アクセス制御においてセキュアでないと見なされることを 指定します。
トリガーのサブジェクト表が行アクセス制御または列アクセス制御を使用 している場合、そのトリガーに対しては NOT SECURED を明示的にも暗黙的にも指定してはなりません。また、NOT SECURED は、ビュー定義にある 1 つ以上の基礎表が行アクセス制御または列アクセス制御を使用しているビューに対して作成されたトリガーにも指定してはなりません。
ENABLE または DISABLE
トリガーの状態を指定します。ENABLE がデフォルトです。
ENABLE
トリガーは入出力操作中に呼び出されます。
DISABLE
トリガーは入出力操作中に呼び出されません。
WRAPPED obfuscated-statement-text
エンコードされたトリガー定義を指定します。WRAP スカラー関数を使用して CREATE TRIGGER ステートメントを エンコードできます。
PROGRAM NAME external-program-name
トリガー用に作成するプログラムの非修飾名を 指定します。external-program-name は、プログラム名の 形式でなければなりません。サービス・プログラム名であってはなりません。
トリガー・アクション
トリガーの起動時に実行するアクションを指定します。トリガー・アクション は、1 つ以上の SQL ステートメントと、ステートメントを実行するかどうかを制御する オプション条件から構成されます。
SET OPTION ステートメント
トリガーを作成するときに使用するオプションを指定します。 例えば、デバッグ可能トリガーを作成する場合は、次のステートメントを 含めることができます。
SET OPTION DBGVIEW = *SOURCE 
各オプションのデフォルト値は、作成時に有効だったオプションによって異なります。詳しくは、SET OPTIONを参照してください。

オプション CNULIGN、CNULRQD、COMPILEOPT、NAMING、SQLCA は、CREATE TRIGGER ステートメントでは使用できません。COMMIT オプションを指定することはできますが、指定しても無視されます。

オプション DATFMT、DATSEP、TIMFMT、および TIMSEP は、OLD ROW または NEW ROW が指定されている場合は使用できません。

WHEN (search-condition)
真、偽、または不明として評価される条件を指定します。起動された SQL ステートメントは、検 索条件 が真と評価された場合にのみ実行されます。WHEN 文節を省略 した場合は、関連の SQL ステートメントは常に実行されます。

INSTEAD OF トリガーでは WHEN 文節を指定してはなりません。

SQL トリガー本体
単一の SQL-procedure-statement (複合ステートメントを含む) を指定します。SQL トリガーの定義についての詳細は、SQL 制御ステートメントを 参照してください。

CONNECT、 SET CONNECTION、 RELEASE、 DISCONNECT、 COMMIT、 ROLLBACK、 SET TRANSACTION、および SET RESULT SETS ステートメントを実行するプ ロシージャーへの呼び出しは、トリガーのトリガー ・アクション 内では使用できません。

UNDO ハンドラーは、トリガーでは使用できません。

トリガー・アクション 内で参照される表、ビュー、別名、特殊タイプ、グローバル変数、ユーザー定義関数、およびプロシージャーはすべて、そのトリガーが作成された時点での現行サーバーに存在していることが必要です。別名が参照している表やビューも、トリガーの作成時に存在していなければ なりません。これには、ライブラリー QTEMP 内のオブジェクトも含まれます。QTEMP 内のオブジェクトはトリガー・ア クション で参照できますが、QTEMP 内のこれらのオブジェクトを除 去しても、トリガーは除去されません。

すべての遷移変数の名前は、サブジェクト表の列名です。サブジェクト表のシステム列名を遷移変数の名前として使用することはできません。

XML タイプの列に対する BEFORE トリガーのトリガー・アクションでは、SET ステートメントで XMLVALIDATE 関数を呼び出したり、XML タイプの値を変更しないでそのまま残したり、SET ステートメントで値を NULL に設定したりする操作を実行できます。

トリガー・アクション 内のステートメントは、プロシージャーまたはユーザー定義関数が異なる活動化グルー プ内で実行される場合、現行サーバー以外のサーバーにアクセスできる プロシージャーまたはユーザー定義関数を呼び出すことができ ます。

トリガーの所有権: SQL 名が指定されている場合、

  • 作成したトリガーが入れられるスキーマと同じ名前のユーザー・プロファイルが存在する場合、トリガーの所有者 はそのユーザー・プロファイルです。
  • その他の場合は、トリガーの所有者 は、この ステートメントを実行しているスレッドのユーザー・プロファイルまたは グループ・ユーザー・プロファイルです。

システム名を指定した場合は、トリガーの所有者 は、この ステートメントを実行しているスレッドのユーザー・プロファイルまたはグループ・ユーザー・プロファイルです。

トリガー権限: トリガー・プログラム・オブジェクトの権限は、次のとおりです。

  • SQL 命名が有効の場合、トリガー・プログラムは *EXCLUDE 共通権限によっ て作成され、その名前のユーザー・プロファイルが存在する場合は、トリガー 名のスキーマ修飾子から権限を借用します。スキーマ修飾子のユーザー・プロファイルが存在しない場合には、トリガー ・プログラムの所有者は、スキーマ修飾子のユーザー・プロファイルになり ます。スキーマ修飾子と同じ名前のユーザー・プロファイルが存在し、その名前が ステートメントの権限 ID と異なっている場合、スキーマ修飾子ライブラリ ー内にトリガー・プログラム・オブジェクトを作成するには、特殊権限の *ALLOBJ と *SECADM が必要です。スキーマ修飾子のユーザー・プロファイルが存在しない場合は、トリガー・ プログラムの所有者は、SQL CREATE TRIGGER ステートメントを実行す るスレッドのユーザー・プロファイルまたはグループ・ユーザー・プロ ファイルになります。グループ・ユーザー・プロファイルがトリガー・プログラム・オブジェクト の所有者になるのは、ステートメントを実行するユーザーのプロファイルで OWNER(*GRPPRF) が指定された場合に限られます。トリガー・プログラムの所有者がグループ・プロファイルのメンバーであり 、ユーザーのプロファイルで OWNER(*GRPPRF) が指定された場合、プログラ ムは、グループ・プロファイルの借用権限を使用して実行されます。
  • システム命名が有効の場合、トリガー・プログラムは *EXCLUDE 共通権限に よって作成され、SQL CREATE TRIGGER ステートメントを実行するスレッドのユ ーザー・プロファイルまたはグループ・ユーザー・プロファイルから権限を 借用します。

実行権限: トリガー SQL 操作を実行するユーザーに、静的なトリガー SQL ステートメント を実行する権限は必要ありません。 トリガー SQL ステートメント は、トリガーの所有者 の権限で実行できます。

REPLACE の規則: REPLACE によってトリガーを再作成する場合は、以下のようになります。
  • 既存のコメントまたはラベルは破棄されます。
  • 権限を持つユーザーは維持されます。オブジェクト所有者は変更される可能性があります。
  • 現在のジャーナル監査は保持されます。
  • トリガーの起動順序は維持されません。

トリガーのアクティブ化: 挿入操作、削除操作、または更新操作のみが、トリガーをアクティブにできます。 参照制約の結果として生じる削除操作は、トリガーを起動しません。 したがって、次のようになります。

  • DELETE トリガー・イベントを含むトリガーは、ON DELETE CASCADE 参照制約を含む 表には追加できません。
  • UPDATE トリガー・イベントを含むトリガーは、ON DELETE SET NULL または ON DELETE SET DEFAULT 参照制約を含む表には追加できません。

トリガーの起動によって、トリガー・カスケード が生じることがあります。これは、あるトリガーの起動によって、SQL ステートメントが実行され、その実行によって別のトリガーが起動されたり、同じトリガーが再度起 動されたりする結果起きるものです。トリガー・アクションでは、最初の変更の結果として更新が行われ、その 結果としてさらにトリガーが起動されるといったことも起こります。トリガー・カスケードを使用すると、有効なトリガー・チェーンを起動するこ とが可能で、単一の削除、挿入、または更新ステートメントによって、デー タベースに対する多数の変更を行うことができます。カスケードのレベル数は、200 またはジョブやプロセスに許容される最大記 憶量のいずれか先に達する値に制限されます。

トリガーを追加して制約を実行する: 既に行が含まれている表に対してトリガーを追加しても、トリガー・アクションは実行されません。 したがって、表内のデータに対して制約を適用するためのトリガーを設計 した場合、既存の行内のデータは、それらの制約を満たしていない可能性が あります。

暗黙的な非表示列に関する考慮事項: トリガーの本体内で、暗黙的な非表示列に対応するトリガー遷移変数を参照することができます。暗黙的な非表示列がある表に対応するトリガー遷移表には、この列が遷移表の一部として格納されます。

同様に、トリガー遷移変数が、暗黙的に非表示と定義される列に対して存在します。 暗黙的な非表示列に対応するトリガー遷移変数は、トリガーの本体内で参照できます。

読み取り専用ビュー: ビューに対して INSTEAD OF トリガーを追加すると、そのビューの読み取り専用特性に影響します。読み取り専用ビューが INSTEAD OF トリガーと従属関係にあると、その INSTEAD OF トリガーに対して定義される操作のタイプによって、このビューが削除可能、挿入可能、または更新可能であるかが定義されます。

遷移変数と INSTEAD OF トリガー: INSTEAD OF トリガー内のすべてのトリガー遷移変数は NULL 可能です。

INSTEAD OF INSERT トリガーで可視の新しい遷移変数の初期値、つまり遷移表の新しい列の初期値は、以下のように設定されます。

  • 列の値が INSERT ステートメントで明示的に指定された場合、対応する新しい遷移変数つまり遷移表の新しい列は、明示的に指定されたその値になります。
  • 列の値が INSERT ステートメントで明示的に指定されないか、または DEFAULT キーワードが指定された場合、対応する新しい遷移変数つまり遷移表の新しい列は、次のようになります。
    • ビュー列が (INSTEAD OF トリガーなしで) 更新可能であり、生成された列または ROWID に基づいていない場合は、基本表の列のデフォルト値になります。
    • その他の場合は、NULL 値になります。

INSTEAD OF UPDATE トリガーで可視の新しい遷移変数の初期値、つまり遷移表の新しい列の初期値は、以下のように設定されます。

  • 列の値が UPDATE ステートメントで明示的に指定された場合、対応する新しい遷移変数つまり遷移表の新しい列は、明示的に指定されたその値になります。
  • UPDATE ステートメントで列に DEFAULT キーワードが明示的に指定された場合、対応する新しい遷移変数つまり遷移表の新しい列は、次のようになります。
    • ビュー列が (INSTEAD OF トリガーなしで) 更新可能であり、生成された列または ROWID に基づいていない場合は、基本表の列のデフォルト値になります。
    • その他の場合は、NULL 値になります。
  • これら以外の場合、対応する新しい遷移変数つまり遷移表の新しい列は、行内の列の既存の値になります。

難読化されたステートメント: CREATE TRIGGER ステートメント は、難読化された形式で実行できます。難読化されたステートメント では、トリガー名のみが判読可能で、その後に WRAPPED キーワードが続きます。 ステートメントの残りは、判読できないが、難読化されたステートメントをサポートするデータベース・サーバー によってデコード可能なように、エンコードされます。難読化されたステートメント は、WRAP スカラー関数を呼び出すことによって生成できます。難読化されたステートメントからトリガーが 作成されるときに指定されるデバッグ・オプションはすべて無視されます。

難読化されたステートメントから作成されたトリガーを 難読化がサポートされていないリリースにリストアすることはできません。したがって、難読化されたステートメントから作成されたトリガーを伴う表を、 難読化がサポートされていないリリースにリストアすることはできません。

SECURED オプションを使用したトリガー作成: トリガーは、 CREATE TRIGGER ステートメントが実行された後はセキュアであると 見なされます。DB2 は SECURED 属性を、トリガー本体のすべてのアクティビティーに対する監査手順をユーザーが確立したことを宣言するアサーションとして扱います。セキュア・トリガーがユーザー定義関数を参照する場合、DB2 では妥当性検査を実行せずに、このようなユーザー定義関数がセキュアであると想定します。このような 関数が機密データにアクセスする可能性がある場合、セキュリティー管理者権限を持つ ユーザーは、それらの関数がそのデータにアクセスすることを許可されていること、 それらの関数のための監査手順が整っていること、および、 後続のすべての ALTER FUNCTION ステートメントがこの監査手順によってレビューされることを 確認する必要があります。

トリガーのサブジェクト表が行アクセス制御 または列アクセス制御を使用している場合、そのトリガーはセキュアでなければなりません。また、トリガーがビューに対して作成され、 ビュー定義内にある基礎表の 1 つ以上がアクティブな行アクセス制御または列アクセス制御を使用している場合、 そういったトリガーにも SECURED を指定する必要があります。

NOT SECURED オプション を使用したトリガー作成: CREATE TRIGGER ステートメント は、トリガーのサブジェクト表が行アクセス制御または列アクセス制御を 使用している場合、または、サブジェクト表がビューであり、ビュー内の基礎表の 1 つ以上が行アクセス制御または列アクセス制御を使用している場合、 エラーを戻します。

遷移変数値および行アクセス制御と列 アクセス制御: 遷移変数および遷移表には行アクセス制御と列アクセス制御は適用 されません。トリガー表に行アクセス制御または列アクセス制御 が適用されている場合、遷移変数および遷移表の初期値には行の許可および列マスク は適用されません。トリガー表に適用されている行アクセス制御および列アクセス制御 は、トリガー本体において参照されている遷移変数および遷移表に対して、 またはトリガー本体内で呼び出されるユーザー定義関数に引数として渡される遷移変数および 遷移表に対しては無視されます。SQL ステートメントが遷移変数または遷移表の機密データにアクセスすることに関してセキュリティー上の問題がないことを確実にするため、SECURED オプションを使用してトリガーを作成してください。トリガーが セキュアでない場合、行アクセス制御および列アクセス制御をトリガー表に対して適用できず、 CREATE TRIGGER ステートメントはエラーを戻します。

複数のトリガー: 1 つの表に対してトリガー SQL 操作と起動時が同一の複数のトリガーを定義できます。 トリガーは、モードおよび作成された順序に基づいて活動化されます。

  • 最初に MODE DB2ROW トリガー (および ADDPFTRG CL コマンドによって作成された固有トリガー) が、作成された順序で起動されます。
  • 次に MODE DB2SQL トリガーが、作成された順序で起動されます。

最初に作成された MODE DB2ROW トリガーが最初に実行され、2 番目に作成された MODE DB2ROW トリガーが 2 番目に実行されるというようになります。

ソース表には、最大 300 のトリガーを追加できます。

REPLACE でトリガーを再作成するときに、活動化順序内の位置は維持されません。トリガーをいったん削除して作成し直した場合と同じ動作になります。

対照表またはトリガー・アクション内で参照されている表への列の追加: トリガーを定義した後で対照表に列を追加する場合は、次の規則が適用されます。

  • 列リストが明示的に定義されていない UPDATE トリガーの場合、新規の 列の更新時にトリガーが起動されます。
  • トリガー・アクション 内の SQL ステートメント がトリガー表を参照している場合、トリガーを再作成するまでは、新規の列 は SQL ステートメントに関連付けられません。
  • OLD_TABLE および NEW_TABLE 遷移表には新規の列は含まれますが、トリガ ーを再作成しない限り、その列を参照することはできません。

トリガー・アクション内の SQL ステートメントによって参照されている表に 列を追加した場合、トリガーを再作成するまでは、新規の列は SQL ステート メントに関連付けられません。

トリガー・アクションの中で参照されている表に対する特権の除去または取り消し: トリガー・アクション の中で参照されている表、ビュー、 別名などのオブジェクトを除去すると、トリガーの起動時に、 そのオブジェクトを参照しているステートメントのアクセス・プランが再作成されます。 その時点でそのオブジェクトが存在していない場合は、対象表について の対応する INSERT、UPDATE、または DELETE 操作は失敗します。

トリガーの作成者がトリガー実行のために必要としている特権が取り消された 場合は、トリガーの起動時に、そのオブジェクトを参照しているステートメント のアクセス・プランが再作成されます。 その時点でその特権が存在していない場合は、対象表について の対応する INSERT、UPDATE、または DELETE 操作は失敗します。

トリガーの実行時のエラー: SQL-trigger-body で SIGNAL ステートメントを実行すると、SQLCODE -438 と、SIGNAL ステートメントで指定した SQLSTATE が返されます。

SQL-trigger-body のステートメントの実行時に発生する他のエラーは、SQLSTATE 09000 と SQLCODE -723 で返されます。

トリガーにおける特殊レジスター: トリガーが活動化される前に特殊レジスターの値は保管され、トリガーからの戻りにおいてリストアされます。 特殊レジスターの値は、トリガーする SQL 操作から継承されます。

トランザクション分離: すべてのトリガーは活動化されると、 トリガーを呼び出すアプリケーション・プログラムの分離レベルがトリガー・プログラムのデフォルトの分離レベルと同じである場合を除いて、 SET TRANSACTION ステートメントを実行します。 トリガーによる操作をすべてそのトリガーを起動させたアプリケーション・プログラムと同じ分離レベルで実行するために、 これが必要になります。 ただし、ユーザーは独自の SET TRANSACTION ステートメントを、トリガーの SQL トリガー本体 内の SQL 制御ステートメント に組み込むことができます。 ユーザーが SET TRANSACTION ステートメントをトリガーの SQL トリガー本体 に組み込んだ場合、トリガーは、 そのトリガーを起動させたアプリケーション・プログラムの分離レベルではなく、 SET TRANSACTION ステートメントで指定された分離レベルで実行されます。

トリガーを起動させたアプリケーション・プログラムが No Commit (COMMIT(*NONE) または COMMIT(*NC)) 以外の分離レベルで実行されている場合、トリガー内 部の操作はコミットメント制御下で実行され、アプリケーションが現行作業 単位をコミットするまでは、コミットやロールバックは行われません。 トリガーの SQL トリガー本体 で ATOMIC が 指定され、ATOMIC トリガーを起動させたアプリケーション・プログラムが 分離レベル No Commit (COMMIT(*NONE) または COMMIT(*NC)) で実行されている場合、 トリガー内部の操作はコミットメント制御下では実行されません。 トリガーを起動させたアプリケーションが分離レベル No Commit (COMMIT(*NONE) または COMMIT(*NC)) で実行されている場合、トリガーの操 作は即時にデータベースに書き込まれ、ロールバックすることはできません。

ある表に対して、物理ファイルトリガー追加 (ADDPFTRG) CL コマンドによっ て定義されたシステム・トリガーと、CREATE TRIGGER ステートメントによっ て定義された SQL トリガーの両方が定義されている場合、システム・トリガ ーが SET TRANSACTION ステートメントを実行して、トリガーを起動した元の アプリケーションと同じ分離レベルで実行されるようにすることをお勧めします。 また、システム・トリガーは、呼び出し元アプリケーションの活動化グルー プ内で実行することもお勧めします。 システム・トリガーを別の活動化グループ (ACTGRP(*NEW)) で実行すると、それらのシステム・トリガーは、呼び出し元アプリケーションの作業単位に 参加せず、SQL トリガーの作業単位にも参加しません。 別の活動化グループで実行されるシステム・トリガーは、コミットメント制 御下で実行したデータベース操作をコミットまたはロールバックする責任が あります。 CREATE TRIGGER ステートメントによって定義された SQL トリガーは 、常に呼び出し元の活動化グループ内で実行されます。

トリガー・アプリケーションがコミットメント制御を使用して実行されてい る場合、SQL トリガーの操作およびカスケード SQL トリガーは、副作業 単位に取り込まれます。トリガーの操作およびカスケード・トリガーが成功した場合、副作業単位に 取り込まれた操作は、トリガー・アプリケーションが現行の作業単位をコミ ットまたはロールバックする時点で、コミットまたはロールバックされます。 呼び出し元と同じ活動化グループ内で実行され、呼び出し元の分離レベルで SET TRANSACTION を実行するシステム・トリガーも、副作業単位に参加しま す。トリガー・アプリケーションがコミットメント制御を使用せずに実行されて いる場合、SQL トリガーの操作もコミットメント制御を使用せずに実行され ます。

トリガーを起動させたアプリケーションが分離レベル No Commit (COMMIT(*NONE) または COMMIT(*NC)) で実行されており、INSERT、 UPDATE、または DELETE ステートメントを実行して、ステートメントの実行中にエラーが発生した場合、その操作のエラーの後は、他のシステム・トリガーや SQL トリガーは起動されません。 ただし、いくつかの変更は既に行われています。トリガー・アプリケーションがコミットメント制御を使用して実行されてい る場合、副作業単位に取り込まれたトリガーの操作は、最初のエラーが検出 された時点でロールバックされ、現行の INSERT、UPDATE、または DELETE ス テートメントの追加のトリガーは起動されません。

パフォーマンスの考慮: トリガーを起動させたアプリケーション・プログラムによって最も頻繁に使用される分離レベルの下にトリガーを作成します。 SET OPTION ステートメントを使用して、明示的に分離レベルを選択することができます。

ROW トリガー (特に、MODE DB2ROW トリガー) は、 TABLE レベル・トリガーよりもパフォーマンスの面でより優れています。

暗黙的に隠される列に関する考慮事項: 暗黙的に隠されると定義した列に対しては、遷移変数が存在します。 暗黙的な隠し列に対応する遷移変数は、トリガーの本体で参照できます。

カタログのトリガー・アクション: トリガーの作成時に、トリガー・アクション は、CREATE TRIGGER ステートメントの結果として、次のように変更されます。

  • 命名方式が SQL 命名に切り替えられます。
  • 未修飾のオブジェクト参照子は、すべて明示的に修飾されます。
  • すべての暗黙の列リスト (例えば、SELECT *、列リストのない INSERT、UPDATE SET ROW) は、実際の列名リストに展開されます。

変更されたトリガー・アクション は、カタログに保管されます。

トリガー・アクション内で参照されている表の名前変更または移動: トリガー・アクション 内で参照されている表は すべて (対象表を含む) 移動や名前変更が可能です。 ただし、トリガー・アクション は、引き続き古い名前やスキーマを参照します。 トリガー・アクション の実行時に参照された表が 見つからないと、エラーになります。そのため、トリガーをいったん除去し た後、トリガーを再作成して、名前変更または移動した表を参照するよう にする必要があります。

日時に関する考慮事項: OLD ROW または NEW ROW が指定されている場合、 日付または時刻定数、あるいはトリガー・アクション 内の SQL ステートメントで使用されている 変数内の日付と時刻のストリング表現は、ISO、EUR、JIS、USA 形式であるか、 または DDS および CRTPF CL コマンドを使用して表を作成した場合は、 その表の作成時に指定された日時形式に一致していなければなりません。 DDS 指定に複数の異なる日時形式が含まれている場合、トリガーは作成できません。

トリガーを無効にする操作: 作動不能トリガー とは、もう起動して利用できなくなったトリガーをいいます。 トリガーが無効になると、対象表または対象ビューに対する INSERT、UPDATE、または DELETE 操作は行えません。 トリガーが無効になるのは、次のような場合です。

  • トリガー・アクション 内の SQL ステート メントが対象表または対象ビューを参照しており、トリガーが自己参照トリガーであるときに、そ の表またはビューをシステム CRTDUPOBJ CL コマンドを使用して複写した場合。
  • トリガー・アクション 内の SQL ステートメント が from ライブラリー内の表またはビューを参照しており、システム CRTDUPOBJ CL コマンドを使用して表またはビューを複写したときに、オブジェクトが新規ライ ブラリー内で見つからない場合。
  • システム RSTOBJ または RSTLIB CL コマンドを使用して表またはビューを新規ライ ブラリーに復元したときに、トリガ ー・アクション が対象表または対象ビューを参照しており、トリガーが自己参 照トリガーである場合。

無効トリガーは、最初にそれを除去してから、CREATE TRIGGER ステート メントを使用して再作成しなければなりません。 対象表に対してトリガー操作および起動時が同一の複数のトリガーが 定義されている場合、トリガーの除去と再作成は、トリガーの起動順序に影 響を与えるので注意が必要です。

トリガー・プログラム・オブジェクト: トリガーが作成されるときに、SQL は、 組み込み SQL ステートメントを含む C ソース・コードが入った一時ソース・ファイルを作成します。 次いで、CRTPGM コマンドを使用して、プログラム・オブジェクトを作成します。 プログラムの作成に使用される SQL オプションは、CREATE TRIGGER ステートメントの実行時に有効なオプションです。 プログラムは、ACTGRP(*CALLER) を使用して作成します。

プログラムは、STGMDL(*SNGLVL) を使用して作成します。STGMDL(*TERASPACE) とさらにコミットメント制御も使用するアプリケーションのためのトリガーを実行する場合は、そのアプリケーション全体を、ジョブを有効範囲とするコミットメント定義 (STRCMTCTL CMTSCOPE(*JOB)) のもとで実行する必要があります。

トリガーは、トリガーの所有者 の借用権限を使用して実行されます。

例 1: 会社が管理する従業員の数を追跡する 2 つのトリガーを作成します。 トリガー表は EMPLOYEE 表で、トリガーは COMPANY_STATS 表の総従業員 数の列を増分または減分します。COMPANY_STATS 表のプロパティーは、次のとおりです。

    CREATE TABLE COMPANY_STATS
      (NBEMP INTEGER,
       NBPRODUCT INTEGER,
       REVENUE DECIMAL(15,0))

この例は、行トリガーを使用して、要約データを別表に保守します。

最初のトリガー NEW_HIRE を作成して、新しい従業員が雇用されるたびに従業員数を増分するようにします。 つまり、新しい行が EMPLOYEE 表に挿入されるたびに、表 COMPANY_STATS の列 NBEMP を 1 だけ増分します。

    CREATE TRIGGER NEW_HIRE
      AFTER INSERT ON EMPLOYEE
      FOR EACH ROW MODE DB2SQL
        UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1    

2 番目のトリガー FORM_EMP を作成して、従業員が会社を辞めるたびに従業員数を減分するようにします。 つまり、表 EMPLOYEE から行が削除されるたびに、表 COMPANY_STATS の列 NBEMP を 1 だけ減分します。

    CREATE TRIGGER FORM_EMP
      AFTER DELETE ON EMPLOYEE
      FOR EACH ROW MODE DB2SQL
      BEGIN ATOMIC
        UPDATE COMPANY_STATS SET NBEMP = NBEMP - 1;
      END 

例 2: トリガー REORDER を作成します。これは、部品レコードが更新され、 該当部品の手持ちの数量が最大在庫量の 10% を下回るたびに出荷要求を出すために、 ユーザー定義関数 ISSUE_SHIP_REQUEST を呼び出します。 ユーザー定義関数 ISSUE_SHIP_REQUEST は、 その部品の最大在庫量から手持ちの数量を差し引いた数量の部品を発注します。 この関数は、同じ PARTNO をオーダーする重複する要求を除去し、 固有のオーダーを該当する製造業者に送信します。

この例は、行トリガーではなく、ステートメント・トリガーとし てトリガーを定義する方法も示しています。WHERE 文節で真と評価された遷 移表内の各行について、その部品の出荷要求が出されます。

    CREATE TRIGGER REORDER
      AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS
      REFERENCING NEW_TABLE AS NTABLE
      FOR EACH STATEMENT MODE DB2SQL
      BEGIN ATOMIC
        SELECT ISSUE_SHIP_REQUEST(MAX_STOCKED - ON_HAND, PARTNO)
        FROM NTABLE
        WHERE ON_HAND < 0.10 * MAX_STOCKED;
      END 

例 3: 表 EMPLOYEE に列 SALARY が含まれると想定します。 従業員の給料を 20% を超えて更新できないようにし、エラーのシグナルを送るトリガー SAL_ADJ を作成します。 75001 の SQLSTATE で戻されるエラーおよび記述を持ちます。 この例では、SIGNAL SQLSTATE ステートメントが、 ビジネス規則に違反する変更を制限するのに役立つことを示しています。

    CREATE TRIGGER SAL_ADJ
      AFTER UPDATE OF SALARY ON EMPLOYEE
      REFERENCING OLD AS OLD_EMP
                  NEW AS NEW_EMP
      FOR EACH ROW MODE DB2SQL
      WHEN (NEW_EMP.SALARY > (OLD_EMP.SALARY *1.20))
      BEGIN ATOMIC
        SIGNAL SQLSTATE '75001'('Invalid Salary Increase - Exceeds 20%');
      END