CREATE TRIGGER 文(基本トリガー)
CREATE TRIGGER (基本) ステートメントは、スキーマ内の基本トリガーを定義し、現在のサーバーでトリガーパッケージを構築します。 トリガーが活動化するたびに、トリガー・パッケージは 1 回以上実行されます。
CREATE TRIGGERの呼び出し(基本)
このステートメントはアプリケーション・プログラムに組み込むことができ、また対話式に出すことができます。 これは、DYNAMICRULES RUN動作が有効になっている場合にのみ、動的に準備できる実行可能なステートメントです。 詳細は、「Authorization IDs and dynamic SQL」 を参照してください。
CREATE TRIGGER(基本)の権限
以下に定義する特権セットには、少なくとも次のいずれかが含まれていなければいけません。
- スキーマに対する CREATEIN 特権
- SYSADM または SYSCTRL 権限
- システム DBADM
インストール SYSOPR 権限 (プロセスの現行 SQLID が SYSINSTL に設定されている場合)
表にトリガーを定義するときは、後述する特権セットに SYSADM 権限あるいは以下のいずれかが含まれていなければいけません。
- トリガー定義に REFERENCING 文節が含まれている場合、トリガーが定義されている表に対する SELECT 特権
- triggered-action の search-condition の表またはビューに対する SELECT 特権
- トリガー・アクションの中のトリガー SQL ステートメントを呼び出すために 必要な特権
- 表にトリガーを定義するための許可。この許可には少なくとも次のいずれかが含まれていなければいけません。
- トリガーが定義されている表に対する TRIGGER 特権
- トリガーが定義されている表に対する ALTER 特権
- 表を含むデータベースに対する DBADM 権限
- SYSCTRL 権限
インストール SYSOPR 権限 (プロセスの現行 SQLID が SYSINSTL に設定されている場合)
- システム DBADM 権限
ビューにトリガーを定義するときは、後述する特権セットに SYSADM 権限あるいは以下のいずれかが含まれていなければいけません。
トリガー定義に REFERENCING 文節が含まれている場合、トリガーが定義されているビューに対する SELECT 特権
- triggered-action の search-condition の表またはビューに対する SELECT 特権
- トリガー・アクションの中のトリガー SQL ステートメントを呼び出すために 必要な特権
- ビューにトリガーを定義するための許可。この許可には少なくとも次のいずれかが含まれていなければいけません。
- トリガーを定義するビューの所有権
- SYSCTRL 権限
- システム DBADM 権限
特権セット:
アプリケーション・プログラムにこの ステートメントを組み込む場合、特権セットは、プランまたはパッケージの所有者が持つ特権となります。 所有者がロールである場合、暗黙的なスキーマの一致は適用されず、また、このロールは上にリストした条件のうちのいずれかを満たしていなければなりません。
このステートメントが動的に準備され、かつ、ROLE AS OBJECT OWNER 文節が指定されたトラステッド・コンテキストの中で実行されていない場合、この特権セットは、プロセスの SQL 許可 ID が持つ特権のセットとなります。 指定されたトリガー名に、スキーマ名 (修飾子) を組み込むことができます。 スキーマ名がプロセスの SQL 許可 ID と異なる場合、下記の条件のいずれか 1 つが満たされていなければなりません。
- 特権セットに SYSADM または SYSCTRL 権限が含まれている。
- プロセスの SQL 許可 ID に、スキーマの CREATEIN 特権がある。
- SECADM 権限
- CREATE_SECURE_OBJECT 特権

CREATE TRIGGER の構文(基本)
トリガ定義
trigger-activation-time
trigger-event
trigger-granularity
triggered-action
SQL トリガー本体
トリガーされたSQLステートメント:
option-list:

CREATE TRIGGER(基本)の説明
- トリガ名
トリガーの名前を指定します。 暗黙的または明示的なスキーマ名を含む名前は、現在のサーバに存在するトリガを識別してはならない。 
この名前は、トリガー・パッケージの作成にも使用されるので、
カタログで既に記述されているパッケージを示すものであってもなりません。 スキーマ名は、トリガー・パッケージのコレクション ID になります。 trigger-name は通常 ID あるいは区切り ID として指定できますが、この名前は通常 ID に関する規則に準拠している必要があります。 詳細は、 暗黙的に作成されるトリガパッケージを参照してください。
特権セットにSYSCTRL特権が含まれている場合、スキーマ名は'SYSTOOLS'とすることができる。 それ以外の場合は、スキーマ名が'SYSADM'、'SYSIBMADM'、'SYSPROC'でない限り、スキーマ名は'SYS'で始まってはならない。
NO CASCADE BEFORE
トリガーが BEFORE トリガーであることを指定します。 Db2 対象テーブルへの挿入、削除、更新操作によって引き起こされた変更を適用する前に、トリガーされたアクションを実行します。 また、トリガー・アクションによって他のトリガーが活動化されることはないことも指定します。これは、BEFORE トリガーのトリガー・アクションには更新、REFRESH TABLE、または TRUNCATE の SQL ステートメントを入れることができないためです。view-name も指定時には、BEFORE を指定してはいけません。 BEFORE トリガーには FOR EACH ROW を指定してください。

- AFTER
- トリガーが AFTER トリガーであることを指定します。 Db2 対象テーブルへの挿入、削除、または更新操作によって生じた変更を適用した後、トリガーされたアクションを実行します。 view-name が指定されている場合は、after を指定してはいけません。
- INSTEAD OF
- トリガーが INSTEAD OF トリガーであることを指定します。 関連したトリガー・アクションは、サブジェクト・ビューに対するアクションを置換します。 指定されたサブジェクト・ビューにおいては、INSTEAD OF トリガーが 1 つだけ、各操作タイプに使用可能です。 Db2 対象ビューに対する挿入、更新、または削除操作の代わりにトリガーされたアクションを実行します。
table-name も指定されているときには、INSTEAD OF は指定しないでください。 INSTEAD OF トリガーの場合は、WHEN 文節を指定することはできません。 FOR EACH STATEMENT は、INSTEAD OF トリガーには指定してはいけません。
ビュー定義で、全選択の最外部の SELECT リストの非数値列では同じコード化スキームを使用する必要があります。
- ON テーブル名
- BEFORE または AFTER トリガー定義のサブジェクト表を指定します。 この名前は、現行サーバーに存在する基本表を示すものでなければなりません。
マテリアライズド・クエリ・テーブル、クローン・テーブル、一時テーブル、補助テーブル、エイリアス、シノニム、リアルタイム統計テーブル、アクセラレータ専用テーブル、カタログ・テーブル、ディレクトリ・テーブルを識別してはならない。
- ON ビュー名
- INSTEAD OF トリガー定義のサブジェクト・ビューを指定します。 この名前は、現行サーバーに存在するビューを示すものでなければなりません。
view-name では、次のどの条件を満足する場合も、ビューを指定しないでください。
- WITH CASCADED CHECK オプション (シンメトリック・ビュー) 付きで定義されているビュー
- シンメトリック・ビューが定義されているビュー
- 異なるコード化スキームまたは CCSID 値を使用してエンコードされたデータを参照するビュー
- ROWID 列である列を持つビュー
- 次のいずれかのタイプの基礎となる列に基づく列を持つビュー
- A LOB、XML、または ROWID 列
- ID 列
- セキュリティー・ラベル列
- 行変更タイム・スタンプ列
- 行開始列
- 行終了列
- トランザクション開始 ID 列
- フィールド・プロシージャーを持つ列があるビュー
- すべての基礎表がカタログ表であるビュー
- すべての基礎表が作成済みのグローバル一時表であるビュー
- すべての基礎表がクローン表であるビュー
- 他のビューが従属しているビュー
- REFERENCING
- 遷移変数の相関名および遷移表の表名を指定します。 トリガー SQL 操作 (挿入、削除、
または更新) によって変更された対象表の行の場合、相関名は特定行の列を示します。 table-identifier には、影響を受ける行の完全セットを指定します。 XML タイプを持つ遷移変数は、トリガー内部で参照できません。 遷移表の列を参照する場合、その列のデータ・タイプを XML にすることはできません。
correlation-names を次のように指定して列名を修飾することにより、トリガー SQL 操作の影響を受けるそれぞれの行をトリガー・アクションが使用できるようになります。
OLD AS 相関名
トリガー SQL 操作に先立って、行の値を示す相関名を指定します。
NEW AS 相関名
トリガー SQL 操作、および既に実行されている BEFORE トリガーの割り当てステートメントによって変更された行の値を示す相関名を指定します。
table-identifiers を次のように指定して使用することによって、トリガー操作の影響を受ける行の完全セットをトリガー・アクションが使用できるようになります。
- OLD_TABLE AS 表識別子
- 実際に変更する前に、トリガー SQL 操作によって変更された行の完全セットの値を示す一時表の名前を指定します。
NEW_TABLE AS テーブル識別子
トリガー SQL 操作、および既に実行されている BEFORE トリガーの割り当てステートメントによって変更された行の完全セットの値を示す、一時表の名前を指定します。 
OLD と NEW の correlation-name は、トリガーに対してそれぞれ 1 つだけ指定できます。 OLD_TABLE と NEW_TABLE の table-identifier は、トリガーに対してそれぞれ 1 つだけ指定できます。 correlation-names と table-identifiers は、すべて互いに固有であることが必要です。
表 1 は、様々なトリガータイプに指定できるトランジション変数とトランジションテーブルの許容される組み合わせをまとめたものです。 OLD correlation-name と OLD_TABLE table-identifier は、トリガー・イベントが削除操作または更新操作である場合のみ有効です。 削除操作の場合、OLD correlation-name は削除される行の列の値を取り込み、OLD_TABLE table-identifier は削除される行のセットにある値を取り込みます。 更新操作の場合、OLD correlation-name は行の列の値を更新操作前の状態で取り込み、OLD_TABLE table-identifier は更新された行のセットにある値を取り込みます。
NEW 相関名と NEW_TABLE テーブル識別子は、トリガー・イベントが挿入操作または更新操作の場合にのみ有効です。 どちらの操作の場合も、NEW correlation-name は挿入または更新される行の列の値を取り込み、NEW_TABLE table-identifier は挿入または更新される行のセットにある値を取り込みます。 BEFORE トリガーの場合、更新される行の値には、BEFORE トリガーのトリガー・アクションにある割り当てステートメントによる変更が加えられます。
表 1. トリガー定義において許される属性の組み合わせ 細分度 アクティブ化時点 トリガー SQL 操作 移行変数許可 1 移行表が許可された1 FOR EACH ROW 前 DELETE OLD なし INSERT NEW なし UPDATE OLD、NEW なし AFTER DELETE OLD OLD_TABLE INSERT NEW NEW_TABLE UPDATE OLD、NEW OLD_TABLE、 NEW_TABLE INSTEAD OF DELETE OLD OLD_TABLE INSERT NEW NEW_TABLE UPDATE OLD、NEW OLD_TABLE、 NEW_TABLE FOR EACH STATEMENT AFTER DELETE なし OLD_TABLE INSERT なし NEW_TABLE UPDATE なし OLD_TABLE、 NEW_TABLE 注:- 遷移表や遷移変数が許されていないところで参照されるとエラーが戻されます。
文字データ・タイプを持つ遷移変数は、サブジェクト表の列のサブタイプと CCSID を継承します。 トリガー・アクションの実行中、遷移変数はホスト変数と同様に 扱われます。 したがって、文字変換が行われる可能性があります。 ただし、ホスト変数とは異なり、遷移変数はビット・データ属性を持つことができ、 ビット・データに対しては文字変換が行われません。 遷移変数は、その変数が対応する表の列がビット・データの場合に、ビット・デー タであると見なされます。
遷移表は読み取り専用なので変更できません。 遷移表は、サブジェクト表の編集プロシージャーまたは検証プロシージャーは継承しませんが、サブジェクト表のコード化スキームとフィールド・プロシージャーは継承します。
それぞれの correlation-name、およびそれぞれの table-identifier の有効範囲は、トリガー定義全体です。
- trigger-granularity
- FOR EACH ROW または FOR EACH STATEMENT
- Db2 がトリガーされたアクションを実行する条件を指定します。
- FOR EACH ROW
- Db2 が、トリガーとなるSQL操作によって変更された対象テーブルの各行に対してトリガーアクションを実行することを指定します。 トリガー SQL 操作では行を変更しないので、トリガー・アクションは実行されません。
- FOR EACH STATEMENT
- Db2 がトリガー操作に対してトリガーされたアクションを1回のみ実行することを指定します。 運用トリガー操作がどの行も変更または削除しない場合でも、
トリガー・アクションは 1 回実行されます。
FOR EACH STATEMENT は、BEFORE トリガーまたは INSTEAD OF トリガーに指定してはいけません。
- MODE DB2SQL
基本トリガーを作成することを示します。
- NOT SECURED または SECURED
- トリガーがセキュアであるとみなされるかどうかを指定します。 NOT SECURED がデフォルトです。
- SECURED
- トリガーがセキュアであるとみなされることを指定します。
トリガーのサブジェクト表が行アクセス制御または列アクセス制御を使用している場合は、トリガーに SECURED を指定する必要があります。 ビュー定義の 1 つ以上の基礎表で行アクセス制御または列アクセス制御が使用される場合、ビューに対して作成されるトリガーにも SECURED を指定する必要があります。
- NOT SECURED
- トリガーがセキュアでないとみなされることを指定します。
NOT SECURED は、そのサブジェクト表が行アクセス制御または列アクセス制御を使用しているトリガーに指定してはなりません。 また、NOT SECURED は、ビュー定義にある 1 つ以上の基礎表が行アクセス制御または列アクセス制御を使用しているビューに対して作成されたトリガーにも指定してはなりません。
- trigger-event
- これを指定すると、サブジェクト表またはビューにトリガー・イベントが適用されるときに、このトリガーに関連するトリガー・アクションが実行されます。
- INSERT
- トリガーが挿入トリガーであることを指定します。 Db2 対象テーブルに挿入操作があるたびに、トリガーされたアクションを実行します。 しかし、insertトリガーがexplainテーブルで定義されており、 Db2 がテーブルに行を追加したことが挿入操作の原因である場合、トリガーされたアクションは実行されません。
- DELETE
- トリガーが削除トリガーであることを指定します。 Db2 対象テーブルで削除操作が行われるたびに、トリガーされたアクションが実行されます。
- UPDATE
- トリガーが更新トリガーであることを指定します。 Db2 対象テーブルで更新操作が行われるたびに、トリガーされたアクションが実行されます。
列名のリストを指定しないと、後で ALTER TABLE ステートメントで追加された列を含めて、 サブジェクト表の任意の列の更新操作によって、トリガー・アクションが活動化されます。
- OF 列名,..
- 指定する各 column-name は、サブジェクト表の列で、
リストに 1 回だけ現れるものでなければなりません。 任意のリスト列の
更新操作によって、トリガー・アクションが活動化されます。
UPDATE OF column-name は、INSTEAD OF トリガーには指定できません。
- triggered-action
- トリガーがアクティブ化されたときに実行するアクションを指定します。 triggered-action は、1 つ以上の SQL ステートメントと、このステートメントが
実行されるかどうかを制御するオプション条件で構成されています。
- WHEN (検索条件 )
- 真、偽、または不明と評価される条件を指定します。 トリガー SQL ステートメントは、search-condition が真と評価された場合のみ実行されます。 WHEN 文節を省略した場合、関連した SQL ステートメントは常に実行されます。
INSTEAD OF トリガーの場合は、WHEN 文節を指定してはいけません。
- SQL トリガー本体
トリガーされたアクションで実行される SQL 文を指定します。 SQL-trigger-bodyに指定できるのは、特定のSQL文だけです。
- トリガー SQL ステートメント
- トリガー本体で唯一のステートメントとして指定できる SQL ステートメントを指定します。
- BEGIN ATOMIC トリガー SQL ステートメント, ... END
- トリガー・アクションのために実行する SQL ステートメントのリストを指定します。 ステートメントは、指定された順序で実行されます。
SQL-trigger-body には、特定の SQL ステートメントのみを指定できます。
トリガー本体には、サポートされていないステートメントを含めることはできません。 表 2は、トリガがBEFORE、AFTER、INSTEAD OFのどれとして定義されているかによって異なる、許可可能なSQL文のリストを示しています。 表の中の「X」は、ステートメントが有効であることを示しています。
表 2. 許される SQL ステートメント SQL ステートメント トリガー起動時間 前 AFTER INSTEAD OF CALL X X X DELETE (検索済み) X X 全選択 X X X INSERT X X MERGE X X REFRESH TABLE X X SET 遷移変数 X SIGNAL X X X TRUNCATE X X UPDATE (検索済み) X X VALUES X X X VALUES INTO X トリガー・アクションのステートメントには、以下の制約事項があります。- ステートメントは、ホスト変数、パラメーター・マーカー、未定義の遷移変数、または宣言済み一時表を参照してはならない。
- ステートメントは、現行サーバーにある表またはビューだけを 参照しなければならない。
- ステートメントは、現行サーバー上のストアード・プロシージャーまたはユーザー定義の関数 だけを呼び出すものでなければならない。 ただし、呼び出されたルーチンは、現行サーバー以外のサーバーにアクセス できる。
- トリガーが BEFORE として定義されている場合、ステートメントに、サブジェクト表を参照する全選択 が含まれていてはならない。
- BUSINESS_TIME 期間の一部である列は変更しないでください。
- トリガーが BEFORE トリガーである場合:
- トリガー本体に DELETE、INSERT、MERGE、REFRESH TABLE、TRUNCATE、UPDATE の各ステートメント、または SELECT FROM data-change-statement を含めてはならず、MODIFIES SQL DATA として定義されているプロシージャーまたは関数を参照してはなりません。
- トリガー本体は、以下のいずれかのステートメントを含むプロシージャーに対して CALL ステートメントを直接的にも間接的にも発行してはなりません。
- ALTER
- COMMENT
- CREATE
- DELETE
- DROP
- EXCHANGE
- GRANT
- ラベル
- LOCK TABLE
- MERGE
- REFRESH TABLE
- RENAME
- REVOKE
- TRUNCATE
- UPDATE
CREATE TRIGGER ステートメントには、16 進グラフィック・ストリング (GX) 定数を含めることはできません。
トリガー・アクションは、影響を受ける行のセットの中で値を参照することができます。 このアクションは、遷移変数と遷移表を用いてサポートされます。
triggered-action で参照されるすべての表、ビュー、別名、シーケンス、ロール、ユーザー定義データ・タイプ、ユーザー定義関数、およびプロシージャーは、トリガーのバージョンを定義するときに現行サーバーに存在している必要があります。 別名が参照する表またはビューも、トリガーのバージョンが定義されるときに存在している必要があります。
WRAPPED 難読化ステートメント・テキスト
FL 500 トリガーのエンコードされた定義を指定します。 WRAP スカラー関数を使用して CREATE TRIGGER ステートメントを
エンコードできます。WRAPPED は、静的 CREATE ステートメントに指定してはなりません。

CREATE TRIGGER(基本)に関する注意事項
- 所有者特権:
- INSTEAD OF トリガーを定義する場合、関連する特権 (ビューに対する INSERT、UPDATE、または DELETE) がそのビューの所有者に与えられます。 特権を付与される所有者は、その特権を他の人に付与することができます。 オブジェクトの所有権に関する詳細は、「権限、特権、権限、マスク、およびオブジェクトの所有権 」を参照してください。
- 実行許可:
- トリガー SQL 操作を実行するユーザーには、SQL-trigger-body を実行する権限は必要ありません。 SQL-trigger-body は、トリガーの所有者の権限を使用して実行します。
- トリガーを作動させる
- 挿入操作、削除操作、または更新操作のみが、トリガーを活動状態にできます。 トリガーの活動化では、
トリガー・カスケードが行われる場合があります。トリガー・カスケード とは、
SQL ステートメントを実行するあるトリガーを活動化すると、他のトリガー (場合によっては再び同じトリガー) が活動化されるような状態をいいます。 また、トリガー・アクションはオリジナルの変更によって更新を発生させる場合もあり、その結果として他のトリガーを活動状態にできます。 トリガー・カスケードを使用すると、大きなトリガーのチェーンが活動化される可能性があります。これにより、単一の挿入、削除、または更新操作の結果として、データベースに大きな変更が加わることがあります。
LOAD ユーティリティでテーブルをロードしても、SHRLEVEL NONE オプションが指定されているか、デフォルトとして受け入れられている場合、テーブルに定義されているトリガはアクティブになりません。 LOAD ステートメントに SHRLEVEL CHANGE オプションが指定されている場合、LOAD ユーティリティーで表がロードされると、トリガーが活動化されます。
- トリガーの追加による制約の実施:
- 既に行を含んでいる表にトリガーを追加しても、triggered-action が実行されることはありません。 したがって、表のデータに対する制約を強化するためにトリガーを設計する場合、 既存の行のデータはその制約を満たさない可能性があります。
- 複数のトリガー:
- トリガー SQL 操作および活動化時期がともに同じである複数のトリガーを 1 つの表に定義することができます。 トリガーは作成された順番に活動化されます。 例えば、最初に作成されたトリガーは最初に実行され、2 番目に作成されたトリガー は 2 番目に実行されます。
- 遷移変数および遷移表:
- triggered-action は、影響を受けた行のセットの中で値を参照することができます。 このアクションは、遷移変数と遷移表を用いてサポートされます。
遷移変数の名前、データ・タイプ、および NULL 可能性の属性は、トリガーが定義されている表の対応する列と同じです。 遷移変数には、影響を受ける行の列の値が含まれます。 遷移変数は、参照が古い値 (更新前) に対するものか、新しい値 (更新後) に対するものかを識別する相関名によって修飾されます。 遷移変数は、検索条件またはトリガー本体の SQL ステートメント内で参照できます。参照できる場所は、トリガー本体の外から発行された参照の場合に変数が許可あれるあらゆる場所です。 BEFORE UPDATE トリガーまたは INSERT トリガーで新規遷移変数に値を割り当てることができます。 更新された行の値には、beforeトリガーの triggered-actionのトランジション変数への代入からの変更が含まれます。
遷移表には、古い値 (更新前) または新しい値 (更新後) のいずれかが指定されている、影響を受けた行の完全なセットが含まれます。 遷移表は読み取り専用であり、AFTER トリガーまたは INSTEAD OF トリガーの triggered-action の中で参照できます。 遷移表の列の名前、データ・タイプ、および NULL の属性は、トリガーが定義されている表の対応する列と同じです。 遷移表は、影響を受けた行の完全なセットを表として扱うことができるようにする関連表 ID を使用して参照されます。 遷移表は、検索条件またはトリガー本体の SQL ステートメント内で参照できます。参照できる場所は、トリガー本体の外から発行された参照の場合に表が許可されるあらゆる場所です。 さらにまた、遷移表の表 ID の前で TABLE キーワードを指定して、遷移表を引数としてユーザー定義の関数やプロシージャーに渡すことができます。 関数またはプロシージャーが呼び出されるときに、遷移表に対して、 表ロケーターが渡されます。
遷移変数または遷移表は、トリガー・アクションの中で呼び出された
プロシージャーから戻されたあと、影響を受けません。これは、対応するパラメーターが、
CREATE PROCEDURE ステートメントの中で、IN、INOUT、または OUT として定義された
かどうかには関係ありません。
table-locator-reference 要素に関する考察:
table-locator-referenceは、トリガ本体で指定してはならない。
- 暗黙的な非表示列に関する考慮事項:
- 暗黙的な隠し列に対応する遷移変数は、トリガーの本体で参照できます。 暗黙的な非表示列がある表に対応する遷移表には、この列が遷移表の一部として格納されます。 同様に、遷移変数が、暗黙的に非表示と定義される列に対して存在します。 暗黙的な非表示列に対応する遷移変数は、トリガーの本体内で参照できます。
- ID の解決:
- 同一の名前は明示的に修飾する必要があります。 名前の修飾によって、名前が列、遷移変数、グローバル変数のどれを指しているのかが明確に示されます。 名前を修飾しない場合や、修飾されていてもまだ未確定である場合は、以下の規則によって名前の解決法が決まります。 新旧両方の遷移変数でそれぞれ相関名が指定される場合、遷移変数への参照は、関連する相関名で修飾する必要があります。 名前は、以下の順序で一致が検査されて解決されます。
- トリガー本体で指定されている表やビューが、そのトリガーの作成時に存在している場合、名前は現在のサーバーで最初に列名として検査されます。 名前が列名として検出されているが、CREATE ステートメントの発行に使用される特権セットにその表またはビューにアクセスするための適切な権限がない場合、エラーが返されます。
- 名前が列として検出されない場合、名前が遷移変数名として検査されます。
- 名前が遷移変数として検出されない場合、名前がグローバル変数として検査されます。
- それでも名前が解決されない場合、エラーが返されます。
- AFTER トリガーおよび INSTEAD OF トリガーの遷移変数に関する考慮事項:
- 遷移変数は、AFTER トリガーまたは INSTEAD トリガーの中では変更できません。
- パッケージの無効化:
- このステートメントは、ターゲット・オブジェクトに依存するすべてのパッケージを無効にすることがあります。また、指定された文節やキーワード、およびその他の要因によっては、カスケード効果により、他の関連オブジェクトに依存するすべてのパッケージを無効にすることがあります。 詳細は、「パッケージが無効になる変更 」を参照してください。
- キャッシュに入れられた動的 SQL ステートメントの無効化:
- このステートメントは、ターゲット・オブジェクト、および場合によってはカスケード効果によって他の関連オブジェクトに依存するキャッシュされた動的 SQL ステートメントを無効にする可能性があります。 詳細は、「キャッシュされた動的ステートメントの無効化 」を参照してください。
- INSTEAD OF トリガーに関する考慮事項:
- ビューに対するINSTEAD OFトリガの追加は、ビューの読み取り専用特性に影響を与えます。 読み取り専用ビューに INSTEAD OF トリガーとの従属関係がある場合は、INSTEAD OF トリガーに定義された操作タイプにより、このビューが削除可能、挿入可能、または更新可能のいずれであるかが定義されます。
INSTEAD OF トリガの作成により、ビュー定義が読み取り専用でない場合、動的ステートメントキャッシュ内の依存パッケージ、プラン、およびステートメントが無効とマークされます。
INSTEAD OF INSERTトリガで表示される新しい遷移変数や新しい遷移テーブル列の初期値は、以下のように設定されます:
- 値が挿入操作の中で列に対して明示的に指定される場合、対応する新規遷移変数は明示的に指定されたその値になります。
- 挿入操作でカラムに明示的に値が指定されていない場合、またはDEFAULT句が指定されている場合、対応する新しい遷移変数が指定されます:
- ビューの列が更新可能 (INSTEAD OF トリガーなしで) な場合、基礎表の列のデフォルト値
- ビューの列が更新可能でない場合、NULL 値
ビューの列が NULL 可能でなく、デフォルトがない場合、値は挿入操作で明示的に指定する必要があります。
INSTEAD OF UPDATE トリガー内で可視の新しい遷移変数のための初期値は、以下のように設定されます。
- 更新操作でカラムに明示的に値が指定された場合、対応する新しい遷移変数はその明示的に指定された値になります
- 更新操作で DEFAULT 節がある列に明示的に指定された場合は、対応する新しい遷移変数は、以下のとおりです。
- ビューの列が更新可能 (INSTEAD OF トリガーなしで) な場合、基礎表の列のデフォルト値
- ビューの列が更新可能でない場合、NULL 値
ビューの列が NULL 可能でなく、デフォルトがない場合、値は更新操作で明示的に指定する必要があります。
- 上記以外の場合は、対応する新しい遷移変数は行内のその列の既存の値です。
- MERGE文の考慮事項:
MERGE文は、挿入、削除、更新の操作を実行できる。
該当するトリガは、実行されるデータ変更操作の MERGE ステートメントに対して起動される。- XML列を含むテーブルに定義されるトリガに関する考慮事項:
- XML 列を含む表に対してトリガーを定義できますが、以下の点に注意してください。
XML 列は、トリガー本体内でトリガー遷移変数を使って参照することはできません。 
遷移表の XML 列は、トリガー本体内で参照できません。 
- SECURED オプションを使用してトリガーを作成する:
- セキュリティー管理者は通常、トリガーがアクセスするデータを調べ、データがセキュアであることを確認し、セキュアなトリガーを作成するための特権を必要とするユーザーに CREATE_SECURE_OBJECT 特権を付与します。 セキュリティー管理者は、トリガーの作成後に、トリガー所有者の CREATE_SECURE_OBJECT 特権を取り消します。
CREATE TRIGGER ステートメントの実行後に、トリガーはセキュアであると見なされます。 Db2 SECURED属性を、トリガー本体のすべての活動に対してユーザーが監査手順を確立したことを宣言するアサーションとして扱います。 安全なトリガーがユーザー定義関数を参照する場合、 Db2 は検証なしでそれらの関数が安全であると仮定します。 この関数が機密データにアクセスできる場合、SECADM 権限を持つユーザーは、この関数が機密データにアクセスすることを許可されること、監査プロシージャーがこの関数のすべてのバージョンに適していること、および後続のすべての ALTER FUNCTION ステートメント、または外部パッケージに対する変更内容がこの監査プロセスで確認されることを確実にする必要があります。
トリガーのサブジェクト表が行アクセス制御または列アクセス制御を使用している場合、そのトリガーはセキュアである必要があります。 ビュー定義の 1 つ以上の基礎表で行アクセス制御または列アクセス制御が使用される場合、ビューに対して作成されるトリガーにも SECURED を指定する必要があります。
- NOT SECURED オプションを使用してトリガーを作成する:
- CREATE TRIGGER ステートメントからエラーが戻されるのは、トリガーのサブジェクト表で行アクセス制御または列アクセス制御が使用されている場合、またはこのトリガーがビューのトリガーであり、ビュー定義の 1 つ以上の基礎表で行アクセス制御または列アクセス制御が使用されている場合です。
- 遷移変数と遷移表に適用されない行アクセス制御と列アクセス制御:
- トリガーのサブジェクト表に行アクセス制御か列アクセス制御が実施される場合、許可および列マスクは、遷移変数および遷移表の初期値には適用されません。 行アクセス制御および列アクセス制御はトリガー表では実施されますが、トリガー本体で参照されるかまたはトリガー本体で呼び出されるユーザー定義関数に引数として渡される遷移変数および遷移表では無視されます。 SQL ステートメントがトリガー・アクションで遷移変数または遷移表の機密データにアクセスすることに関してセキュリティー上の問題がないようにするため、SECURED オプションを使用してトリガーを作成してください。 トリガーがセキュアでない場合、CREATE TRIGGER ステートメントを実行するとエラーが返されます。
- 保留定義変更に関する制約事項は、以下のとおりです。
- 保留している定義変更がある表でトリガーが定義されている場合、CREATE TRIGGER は許可されません。
- EXPLAIN のための特殊プラン、ステートメント、および関数表に関する考慮事項:
- PLAN_TABLE、 DSN_STATEMNT_TABLE、または DSN_FUNCTION_TABLE に関するトリガーを作成できます。 しかし、これらのテーブルで定義された挿入トリガーは、 Db2 がテーブルに行を追加する際に起動されません。
- 従属オブジェクト:
- トリガーは、トリガー表とトリガー本体で参照されているオブジェクトに従属します。
- サブジェクト表または triggered-action で参照される表への列の追加:
- トリガーの定義後にサブジェクト表に列が追加された場合、次の規則が適用されます。
- 列名の明示リストなしで定義されている更新トリガーの場合、新しい列への 更新によってトリガーが起動されます。
- triggered-action でサブジェクト表を参照する場合、トリガー・パッケージが再バインドされないうちは SQL ステートメントから新しい列にアクセスできません。
- OLD_TABLE 遷移表と NEW_TABLE 遷移表は新しい列を含んでいますが、トリガーを再作成しない限りこの列は参照できません。 遷移表がユーザー定義関数またはストアード・プロシージャーに 渡される場合は、そのユーザー定義関数またはストアード・プロシージャーを、表の新しい定義で再作成 して (つまり、関数またはプロシージャーをドロップして、再作成する必要がある)、ユーザー定義関数またはストアード・プロシージャーのパッケージを再バインドする必要があります。
triggered-action で参照される任意の表に列を追加する場合、トリガー・パッケージが再バインドされないうちは SQL ステートメントからその新しい列にアクセスできません。
- サブジェクト表または triggered-action で参照される表からの列のドロップ:
- トリガーが定義されている表から列をドロップすることはできません。
- トリガー・アクションが参照する列の属性の変更:
- トリガーが定義されている対象の表 (サブジェクト表) の中で列が変更された場合、変更は処理され、従属するトリガー・パッケージは無効になります。
- トリガーの定義先の表または triggered-action で参照される表の名前変更:
- トリガーの定義先の表 (サブジェクト表) を名前変更することはできません。 サブジェクト表の場合を除いて、 トリガー・アクションの SQL ステートメントが参照する表の名前は変更できます。 このような表の名前を変更した後は、トリガーをドロップしてから、名前を変更された 表を参照するようにトリガーを再作成してください。
- トリガーの定義先の表またはビューのドロップ:
- トリガーの定義先の表またはビューがドロップされると、トリガーもドロップされます。
- triggered-action で参照されているオブジェクトに対する特権のドロップまたは取り消しの影響:
- トリガー本体で参照されているオブジェクトをドロップするか、トリガー本体で参照されているオブジェクトに対する特権を取り消すと、以下の結果が生じる可能性があります。
- トリガー・アクションの SQL ステートメントの内部で参照または使用される 任意の表、ビュー、別名、または索引をドロップすると、トリガーとそのパッケージが無効に なります。
- 参照されているシノニムをドロップしても、トリガーまたはパッケージに影響はありません。
- トリガー・アクションの SQL ステートメントによって参照されるユーザー定義関数をドロップすることは許されません。 エラーが発生します。
- トリガー・アクションの SQL ステートメントによって参照されるシーケンスをドロップすることは許されません。 エラーが発生します。
- トリガーが依存する特権を取り消すと、トリガーとそのパッケージが 無効になります。 トリガー・パッケージが再バインドされるときに、適切な特権が存在していない場合、オブジェクトを参照する SQL ステートメントは失敗します。
- トリガーでのエラー処理:
- トリガーは、その他の SQL ステートメントと同様にエラーを返すことがあります。 アプリケーションは、トリガーを呼び出す際に予想できるエラーを認識している必要があります。
- トリガーおよびグローバル変数:
- トリガーによって参照されるグローバル変数の内容は、トリガー SQL 操作 (削除、挿入、更新) から継承されます。
- 特殊レジスター:
- トリガー本体で使用される特殊レジスターの値は、トリガーが活動化されるときに決定されます。 CURRENT PACKAGESET 特殊レジスターの値はトリガーのスキーマ名に設定され、その他の特殊レジスターの値は、トリガー SQL 操作 (挿入、更新、削除) から継承されます。 特殊レジスターの値は、トリガーが活動化されるときに保存され、トリガーから戻る際にリストアされます。 CURRENT DATE、CURRENT TIME、および CURRENT TIMESTAMP の特殊レジスターは、トリガーから戻るときにリストアされません。
- ストアード・プロシージャーの結果セット:
- トリガーが結果セットを戻すストアード・プロシージャーを呼び出す場合、そのトリガーを活動化したアプリケーションはその結果セットにアクセスできません。
- トランザクションの分離:
- SQL-trigger-body にあるすべてのステートメントは、そのトリガーで有効になっている分離レベルで実行されます。
- プロセッサー時間の制限:
Db2 リソース制限機能を使用すると、SELECT や SQL データ変更文のような動的で操作性の高い SQL 文の最大プロセッサ時間を指定できます。 トリガーの実行はトリガーとなる SQL ステートメントの一部としてカウントされます。 
- トリガーのバインド時のエラー:
- CREATE TRIGGER ステートメントをバインドするとき、トリガー・アクション内の SQL ステートメントは完全に解析されない場合があります。 それらのステートメントの構文エラー が、CREATE TRIGGER ステートメントが実行されるまで捕らえられない場合があるからです。
- トリガー用に生成されるパッケージの特性:
- 最トリガーに関連するパッケージは、以下のようにして名前を指定します。
- location は、CURRENT SERVER 特殊レジスターの値に設定されます。
- パッケージ用の collection-id (スキーマ) は、トリガーのスキーマ修飾子と同じです。
- package-id は、トリガーの名前と同じです。
- version-id は空ストリングです。
Db2 は、以下の初期属性を持つトリガパッケージを作成します(これらの属性のいくつかは、REBIND TRIGGER PACKAGEコマンドを使用して変更することができます):

- ACTION(ADD)
- ARCHIVESENSITIVE(YES)
- BUSTIMESENSITIVE(YES)
- CURRENTDATA(NO)
- dbプロトコル(drda)
- DEGREE(1)
- DESCSTAT(DESCSTAT サブシステム・パラメーターの値)
- DYNAMICRULES(BIND)
- イネーブル(*)
- ENCODING(0)
- EXPLAIN(NO)
- FLAG(I)
- ISOLATION(CS)
- REOPT(NONE)
- NODEFER(PREPARE)
- OPTHINT
- OWNER (許可 ID) または ROLE
- PATH(パス)
- RELEASE(COMMIT)
- ROUNDING(CURRENT DECFLOAT ROUNDING MODE 特殊レジスターからの値)
- SQLERROR(NOPACKAGE)
- SYSTIMESENSITIVE(YES)
- QUALIFIER(許可 ID)
- VALIDATE(BIND)

OWNER、QUALIFIER、および PATH の値は、CREATE TRIGGER ステートメントがプログラム
に組み込まれているか、対話式に出されたかに応じて設定されます。 プログラムに組み込まれている場合、OWNER と QUALIFIER は、パッケージまたは
プラン所有者と修飾子になります。 PATH は PATH バインド・オプションの値です。 ステートメントが対話式に出された場合、OWNER と QUALIFIER は両方とも SQL 許可 ID に
なります。 PATH は CURRENT PATH 特殊レジスターの中の値です。
複数バージョンのトリガー・パッケージは使用できません。 基本トリガー・パッケージを明示的に再バインドするには、REBIND TRIGGER PACKAGE コマンドを使用します。 バインド・コマンドに対してトリガー・パッケージの名前を指定するには、そのトリガー名が通常 ID の規則に準拠しなければなりません。
オブジェクトまたはオブジェクトが依存する特権がドロップされるか取り消されると、 トリガー・パッケージは無効になります。 次にトリガーが起動された際に、 Db2 は無効なトリガーパッケージの再割り当てを試みます。 自動再バインドが 不成功に終わると、トリガー・パッケージは無効のままになります。
BIND COPY コマンドを使用する場合のように、トリガー・パッケージから別の パッケージを作成することはできません。 トリガー・パッケージをドロップする唯一の方法は、 トリガーまたはサブジェクト表のドロップです。 トリガーをドロップするとトリガー・パッケージがドロップされ、 サブジェクト表をドロップするとトリガーおよびトリガー・パッケージがドロップされます。
トリガーが活動化するたびに、トリガー・パッケージは 1 回以上実行されます。
- SQL プロセッサー・プログラムに関する考慮事項:
- SPUFI、 Db2 command line processor、 DSNTEP2 などのSQLプロセッサプログラムは、セミコロンで終わるトリガーアクションのSQLステートメントを正しく解析できない場合があります。 これらのプロセッサー・プログラムは、複数の SQL ステートメント (間を終了文字で 分離されている) を入力として受け入れます。 セミコロンをSQL文の終端記号として使用するプロセッサプログラムは、セミコロンが埋め込まれたCREATE TRIGGER文を切り捨て、その一部のみを Db2 に渡す可能性があります。 そのため、これらのプロセッサー・プログラムの場合は、SQL 終了文字の変更が必要に なる可能性があります。 SPUFIと DSNTEP2 のターミネータ文字を変更する方法については、 SPUFI入力データセットにおけるSQLターミネータ文字の設定と、 DSNTEP2 および DSNTEP4 サンプルプログラムを参照してください。
アプリケーションの互換性レベル:
トリガー本体の SQL ステートメントは、有効になっているアプリケーションの互換性オプションで指定されている動作に準拠する必要があります。 トリガーの処理に使用されるアプリケーションの互換性の値は、SYSIBM.SYSPACKAGE カタログ表の APPLCOMPAT 列に記録されます。
- 代替構文およびシノニム:
- Db2ファミリー内のDb2または他の製品の以前のリリースとの互換性を提供するために、Db2は以下のキーワードをサポートします。
- OLD_TABLE のシノニムとして OLD TABLE
- NEW_TABLE のシノニムとして NEW TABLE
難読化されたステートメント:
FL 500A CREATE TRIGGER 文は難読化された形式で実行できます。 難読化されたステートメントでは、トリガー名および WRAPPED キーワードのみを判読できます。 ステートメントのその他の部分は、読み取り不能な、しかも難読化ステートメントをサポートするデータベース・サーバーでデコード可能な方法でエンコードされます。 WRAP スカラー関数は、難読化されたステートメントを作成します。 難読化されたステートメントからトリガーが
作成されるときに指定されるデバッグ・オプションはすべて無視されます。
CREATE TRIGGER の例(基本)
- 例 1
会社が管理する従業員の数を追跡する 2 つのトリガーを作成します。 サブジェクト表は EMPLOYEE 表で、COMPANY_STATS 表の従業員の 総数の列の増分と減分を起動します。 表には次の列があります。
- EMPLOYEE 表: ID、NAME、ADDRESS、および POSITION
- COMPANY_STATS 表: NBEMP、NBPRODUCT、および REVENUE
この例は、行トリガーで遷移変数を使用して、別の表の合計データを保守する方法を 示しています。
最初のトリガー NEW_HIRE を作成して、このトリガーが新しく人を雇うたびに従業員数を 増分するようにします。すなわち、EMPLOYEE 表に新しい行が挿入されるたびに、COMPANY_STATS 表 の NBEMP 列の値を 1 だけ増やします。
CREATE TRIGGER NEW_HIRE AFTER INSERT ON EMPLOYEE FOR EACH ROW MODE DB2SQL BEGIN ATOMIC UPDATE COMPANY_STATS SET NBEMP = NBEMP + 1; END
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 を作成し、ユーザー定義関数 ISSUE_SHIP_REQUEST を呼び出して、部品レコードが更新され、影響を受ける部品の手持ち数量が最大在庫数量の 10% 未満になるたびに出荷要求を発行します。 ユーザー定義関数 ISSUE_SHIP_REQUEST は、パーツの最大在庫数量から手元数量を引いた数量のパーツを発注し、さらにこの要求が適切な製造業者に確実に届くようにします。
パーツ・レコードは PARTS 表にあります。 この表には他にも列がありますが、 トリガーが起動されるのは、列 ON_HAND と MAX_STOCKED が更新されたときだけです。

CREATE TRIGGER REORDER AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS REFERENCING NEW AS NROW FOR EACH ROW MODE DB2SQL WHEN (NROW.ON_HAND < 0.10 * NROW.MAX_STOCKED) BEGIN ATOMIC VALUES(ISSUE_SHIP_REQUEST(NROW.MAX_STOCKED - NROW.ON_HAND, NROW.PARTNO)); END
- 例 3
例 2 のシナリオを繰り返します。ただし、VALUES ステートメントの代わりに全選択を使用してユーザー定義関数を呼び出します。 この例では、行トリガーの代わりにステートメント・トリガーとしてトリガーを定義する方法も示します。 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
- 例 4
- 表 EMPLOYEE に列 SALARY が含まれているとします。 20% を超える従業員の給与の更新を防止し、このようなエラーの信号を出す
トリガー、SAL_ADJ を作成します。 エラーとともに、SQLSTATE「75001」と記述を戻します。 この例は、SIGNAL ステートメントが
ビジネス規則に違反するような変更を制限するために便利であることを示しています。

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
- 例 5
- 以下のステートメントにより、表 WEATHER (温度値を華氏で保管する) とビュー CELSIUS_WEATHER が作成され、華氏ではなく摂氏で作業することを希望するユーザーに対して作成されるとします。
以下の INSTEAD OF トリガーを CELSIUS_WEATHER ビューで使用して、摂氏の値を華氏の値に変換し、さらに、華氏の値を WEATHER 表に挿入します。CREATE TABLE WEATHER (CITY VARCHAR(25), TEMPF DECIMAL(5,2)); CREATE VIEW CELSIUS_WEATHER (CITY, TEMPC) AS SELECT CITY, (TEMPF-32)/1.8 FROM WEATHER;
CREATE TRIGGER CW_INSERT INSTEAD OF INSERT ON CELSIUS_WEATHER REFERENCING NEW AS NEWCW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC INSERT INTO WEATHER VALUES (NEWCW.CITY, 1.8*NEWCW.TEMPC+32); END

例6

株価の変化を記録して追跡するアプリケーションについて考えてみます。 データベースには、CURRENTQUOTE および QUOTEHISTORY という 2 つの表が含まれています。 CURRENTQUOTE には、列 SYMBOL、QUOTE、および STATUS があります。 QUOTEHISTORY には、列 SYMBOL、QUOTE、および QUOTE_TIMESTAMP があります。CURRENTQUOTE の QUOTE 列が更新されると、新規見積価格はタイム・スタンプと一緒に QUOTEHISTORY 表にコピーされる必要があります。 また、CURRENTQUOTE の STATUS 列も、次のようなカブの状況が反映されるように更新します。

1 値上がり中 2 新しい年内最高額 3 値下がり中 4 新しい年内最低額 5 安定価格 
これらのタスクを実行する CREATE TRIGGER ステートメントは次のとおりです。
トリガー STOCK_STATUS は以下の状況を設定します。
CREATE TRIGGER STOCK_STATUS NO CASCADE BEFORE UPDATE OF QUOTE ON CURRENTQUOTE REFERENCING NEW AS NEWQUOTE OLD AS OLDQUOTE FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET NEWQUOTE.STATUS = CASE WHEN NEWQUOTE.QUOTE > (SELECT MAX(QUOTE) FROM QUOTEHISTORY WHERE SYMBOL = NEWQUOTE.SYMBOL AND YEAR(QUOTE_TIMESTAMP) = YEAR(CURRENT DATE) ) THEN 'High' WHEN NEWQUOTE.QUOTE < (SELECT MIN(QUOTE) FROM QUOTEHISTORY WHERE SYMBOL = NEWQUOTE.SYMBOL AND YEAR(QUOTE_TIMESTAMP) = YEAR(CURRENT DATE) ) THEN 'Low' WHEN NEWQUOTE.QUOTE > OLDQUOTE.QUOTE THEN 'Rising' WHEN NEWQUOTE.QUOTE < OLDQUOTE.QUOTE THEN 'Dropping' WHEN NEWQUOTE.QUOTE = OLDQUOTE.QUOTE THEN 'Steady' END; ENDトリガー RECORD_HISTORY は、QUOTEHISTORY 表の変化を記録します。
CREATE TRIGGER RECORD_HISTORY AFTER UPDATE OF QUOTE ON CURRENTQUOTE REFERENCING NEW AS NEWQUOTE FOR EACH ROW MODE DB2SQL BEGIN ATOMIC INSERT INTO QUOTEHISTORY VALUES (NEWQUOTE.SYMBOL, NEWQUOTE.QUOTE, CURRENT TIMESTAMP); END
