Hitachi

ノンストップデータベース HiRDB Version 10 SQLリファレンス


3.18.1 CREATE TRIGGERの形式と規則

〈この項の構成〉

(1) 機能

指定した表への操作(INSERT文,UPDATE文,及びDELETE文)を契機に,自動的にSQLを実行する動作(トリガ)を定義します。

(2) 使用権限

自分が所有する表に対してトリガを定義できます。

(3) 形式

 CREATE TRIGGER 〔認可識別子.〕トリガ識別子
    トリガ動作時期
    トリガ契機
    ON 〔認可識別子.〕表識別子
    〔REFERENCING 新旧値別名リスト〕
    トリガ動作
    〔SQLコンパイルオプション〔SQLコンパイルオプション〕…〕
    〔WITH PROGRAM〕
 
 トリガ動作時期::={BEFORE|AFTER}
 トリガ契機::={INSERT|DELETE|UPDATE〔OF 列名〔,列名〕…〕}
 新旧値別名リスト::=新旧値別名〔新旧値別名〕
 新旧値別名::={OLD 〔ROW〕 〔AS〕 旧値相関名
          |NEW 〔ROW〕 〔AS〕 新値相関名}
 旧値相関名,新値相関名::=相関名
 トリガ動作::=〔{FOR EACH ROW|FOR EACH STATEMENT}〕
         〔WHEN (探索条件)〕
         トリガSQL文
 トリガSQL文::=SQL手続き文
 SQLコンパイルオプション::={ISOLATION データ保証レベル 〔FOR UPDATE {EXCLUSIVE|COMPATIBLE}〕
                |OPTIMIZE LEVEL SQL最適化オプション
                         〔,SQL最適化オプション〕…
                |ADD OPTIMIZE LEVEL SQL拡張最適化オプション
                         〔,SQL拡張最適化オプション〕…
                |SUBSTR LENGTH 文字の最大長 }

(4) オペランド

(a) 〔認可識別子.〕トリガ識別子

認可識別子

定義するトリガの所有者の認可識別子を指定します。省略した場合,CREATE TRIGGERを実行するユーザの認可識別子が仮定されます。

トリガ識別子

定義するトリガの名前を指定します。

(b) トリガ動作時期::={BEFORE|AFTER}

BEFORE

表に対する操作の前に,トリガ動作を実行します。

BEFOREを指定した場合,データを更新するSQL(INSERT文,UPDATE文,及びDELETE文),CALL文,及びデフォルトコンストラクタ関数以外の関数呼出しは,トリガSQL文中には指定できません。

トリガ動作時期にBEFOREを指定したトリガを,BEFOREトリガといいます。

AFTER

表に対する操作の後に,トリガ動作を実行します。

トリガ動作時期にAFTERを指定したトリガを,AFTERトリガといいます。

(c) トリガ契機::={INSERT|DELETE|UPDATE〔OF 列名〔,列名〕…〕}

どのような操作をしたときにトリガを実行するかを指定します。

INSERT

表に行を挿入したときにトリガを実行します。トリガ契機にINSERTを指定したトリガをINSERTトリガといいます。

トリガ契機にINSERTを指定した場合,新旧値別名にOLD〔ROW〕〔AS〕旧値相関名は指定できません。

DELETE

表の行を削除したときにトリガを実行します。トリガ契機にDELETEを指定したトリガをDELETEトリガといいます。

トリガ契機にDELETEを指定した場合,新旧値別名にNEW〔ROW〕〔AS〕新値相関名は指定できません。

UPDATE

表の行を更新したときにトリガを実行します。トリガ契機にUPDATEを指定したトリガをUPDATEトリガといいます。

トリガ契機にUPDATEを指定した場合,トリガ動作条件を満たしていれば,更新前後で値が同じでもトリガを実行します。

OF 列名〔,列名〕…

特定の列を更新したときにトリガを実行したい場合,OF 列名〔,列名〕…を指定します。ここで指定した列を,トリガ契機列といいます。

トリガ契機列についての規則を次に示します。

  1. 列名には,トリガを定義する表の列名を指定します。

  2. 列名は重複して指定できません。

  3. 繰返し列を指定した場合,その列に対するADD句,又はDELETE句だけのUPDATE文でも,トリガを実行します。

  4. トリガ契機列を省略した場合,対象表のすべての列名(予備列を除く)が仮定されます(トリガ定義後に追加した列も含まれます)。また,ADD句,又はDELETE句だけのUPDATE文でも,トリガを実行します。

  5. 予備列は指定できません。

(d) 〔認可識別子.〕表識別子

トリガを定義する実表の表名を指定します。

トリガは,自分の永続実表にだけ定義できます。ビュー表及び一時表に対してトリガは定義できません。

(e) REFERENCING 新旧値別名リスト::=新旧値別名〔新旧値別名〕

トリガ定義中で更新前後の行を参照する場合に,別名を指定します。

新旧値別名には,OLD〔ROW〕〔AS〕旧値相関名,又はNEW〔ROW〕〔AS〕新値相関名を,それぞれ1回だけ指定できます。

(f) 新旧値別名::={OLD 〔ROW〕 〔AS〕 旧値相関名|NEW 〔ROW〕 〔AS〕 新値相関名}

旧値相関名::=相関名

新値相関名::=相関名

更新前,又は更新後の行に名前を付けて参照する場合に指定します。

新旧値別名についての規則を次に示します。

  1. ROW及びASは,指定してもしなくても同じです。

  2. 旧値相関名と新値相関名には,同じ相関名は指定できません。

  3. 旧値相関名,又は新値相関名に指定した相関名の有効範囲は,トリガ定義全体になります。

  4. BEFOREトリガで新値相関名で修飾した列を更新した場合は,その更新内容が表に反映されます。ただし,BEFOREトリガでは,次の列を新値相関名で修飾した更新はできません。更新した場合は実行時エラーとなります。

    ・SYSTEM GENERATEDを指定した列

    また,トリガ契機がINSERTのBEFOREトリガでは,次の列を新値相関名で修飾した更新はできません。更新した場合は実行時エラーとなります。

    ・分割表(フレキシブルハッシュ分割表を除く)の分割キーに指定した列

    BEFOREトリガの場合,新値相関名で修飾して更新するときでも,更新する前の挿入値(トリガ契機がINSERTの場合),又は更新値(トリガ契機がUPDATEの場合)は,指定した列に挿入又は更新できる値でなければなりません。例えば,非ナル値制約ありの列には,トリガ動作で更新する前の挿入値又は更新値としてNULLは指定できません。ただし,一意性制約については,トリガ動作で更新した後の値が一意性制約を満たしていれば挿入又は更新ができます。

  5. 繰返し列及び抽象データ型列は,新値相関名,及び旧値相関名で修飾して参照できません(トリガ定義中で,トリガを定義する表中の繰返し列及び抽象データ型列は参照できません)。

  6. 旧値相関名,及び新値相関名には,ROWは指定できません。

  7. 予備列は,新値相関名,及び旧値相関名で修飾して参照できません。

OLD 〔ROW〕 〔AS〕 旧値相関名

更新前の行に名前を付けて参照する場合に指定します。

旧値相関名で修飾した列が保持する値は,トリガの契機となるSQLの実行前の値です。UPDATE文の場合は更新前の値,DELETE文の場合は削除する行の列値となります。

NEW 〔ROW〕 〔AS〕 新値相関名

更新後の行に名前を付けて参照する場合に指定します。

新値相関名で修飾した列が保持する値は,トリガの契機となるSQLの実行結果の値です。UPDATE文の場合は更新後の値,INSERT文の場合は挿入値となります。ただし,トリガ中で新値相関名で修飾した列を更新した場合は,更新した値を引き継ぎます。

(g) トリガ動作::=〔{FOR EACH ROW|FOR EACH STATEMENT}〕〔WHEN (探索条件)〕トリガSQL文

FOR EACH ROW

トリガを,更新した行単位に実行する場合に指定します。トリガ動作にFOR EACH ROWを指定したトリガを,行単位トリガといいます。

FOR EACH ROWを指定した場合,表を1行更新するごとにトリガを実行します。

FOR EACH STATEMENT

トリガを,SQL文単位に実行する場合に指定します。トリガ動作にFOR EACH STATEMENTを指定したトリガを,文単位トリガといいます。

FOR EACH STATEMENTを指定した場合,一つのSQL文ごとにトリガを実行します。更新対象の行がない場合でもトリガを実行します。

FOR EACH STATEMENTを指定した場合,新旧値別名リストは指定できません。

探索条件

トリガ契機が発生したとき,ここに指定した条件が真になる場合にトリガSQL文を実行します。この探索条件を,トリガ動作条件といいます。

トリガ動作条件を省略した場合,指定したトリガ契機が発生すると必ずトリガSQL文を実行します。トリガ動作条件には,次のものは指定できません。

  • 副問合せ

  • 集合関数又はSQL/XML集合関数

  • ウィンドウ関数

  • 繰返し列

  • 埋込み変数,?パラメタ,SQL変数,及びSQLパラメタ

  • 次のデータ型の列

    ・BLOB(ただし,スカラ関数LENGTH,スカラ関数POSITION,及びユーザ定義関数の関数呼出しの中では指定できます)

    ・最大長32,001バイト以上のBINARY(ただし,スカラ関数LENGTH,スカラ関数POSITION,及びユーザ定義関数の関数呼出しの中では指定できます)

    ・抽象データ型

  • 構造化繰返し述語

  • プラグイン関数

  • 結果が抽象データ型となる値式(値式中にも指定できません)

  • XMLコンストラクタ関数

  • SQL/XMLスカラ関数

  • 予備列

トリガ動作条件中でトリガを定義する表の列を参照する場合は,新旧値相関名で修飾してください(修飾なし,又は表名での修飾は指定できません)。

トリガSQL文

SQL手続き文を指定します。SQL手続き文については,「ルーチン制御SQL」を参照してください。

トリガSQL文として指定するSQL手続き文には,次の制限があります。

  1. トリガを定義している表の表名は指定できません。

  2. トリガを定義している表の列を,修飾なし,又は表名で修飾して指定することはできません(新旧値別名で修飾した列は指定できます)。列を新旧値相関名で修飾した場合,トリガSQL文中でこの列指定を指定できる箇所は,SQL文中でSQLパラメタを指定できる箇所と同じになります。SQLパラメタを指定できる箇所については,「埋込み変数,標識変数,?パラメタ,SQLパラメタ,及びSQL変数」を参照してください。ただし,LIMIT句にはこの列指定は指定できません。

  3. ROLLBACK文,COMMIT文,及びPURGE TABLE文は指定できません。また,CALL文でこれらを指定した手続きが呼び出された場合は,実行時エラーとなります。

  4. JAVAストアドプロシジャ,及びGET_JAVA_STORED_ROUTINE_SOURCE指定は指定できません。また,CALL文でJAVAストアドプロシジャを指定した手続きが呼び出された場合は,実行時エラーとなります。

  5. トリガSQL文中で,新値相関名,又は旧値相関名で修飾して指定する列の個数は30,000以下にしてください。

(h) SQLコンパイルオプション

::={ISOLATION データ保証レベル 〔FOR UPDATE {EXCLUSIVE|COMPATIBLE}〕
    |OPTIMIZE LEVEL SQL最適化オプション〔,SQL最適化オプション〕…
    |ADD OPTIMIZE LEVEL SQL拡張最適化オプション〔,SQL拡張最適化オプション〕…
    |SUBSTR LENGTH 文字の最大長 }

SQLコンパイルオプションには ISOLATION,OPTIMIZE LEVEL,ADD OPTIMIZE LEVEL,SUBSTR LENGTHをそれぞれ1回しか指定できません。

〔ISOLATION データ保証レベル 〔FOR UPDATE {EXCLUSIVE|COMPATIBLE}〕〕

SQLのデータ保証レベルを指定します。

データ保証レベル

データ保証レベルとは,トランザクションのどの時点までデータの内容を保証するかのレベルをいいます。次に示すデータ保証レベルを指定できます。

  • 0

    データの内容を保証しない場合に指定します。0レベルを指定すると,ほかのユーザが更新中のデータでも,更新完了を待たないで参照できます。ただし,参照する表が共用表の場合,ほかのユーザが排他モードでLOCK文を実行しているときには,排他解除待ちとなります。

  • 1

    検索処理の終了までデータの内容を保証したい場合に指定します。1レベルを指定すると,検索処理が終了するまで(HiRDBがページ,又は行を見終わるまで)1度検索したデータをほかのユーザは更新できません。

  • 2

    トランザクションの終了まで1度検索したデータの内容を保証したい場合に指定します。2レベルを指定すると,トランザクションが終了するまで1度検索したデータをほかのユーザは更新できません。

〔FOR UPDATE{EXCLUSIVE|COMPATIBLE}〕

トリガ中でFOR UPDATE句を指定した(FOR UPDATEが仮定される場合を含む)カーソル又は問合せに対して,SQLコンパイルオプションで指定したデータ保証レベルに関係なく,常にWITH EXCLUSIVE LOCKを仮定する場合に指定します。

このオペランドを省略した場合,EXCLUSIVEを仮定します。ただし,0904互換モードを適用している場合はCOMPATIBLEを仮定します。

バージョン09-50より前のHiRDBでFOR UPDATE EXCLUSIVEを省略したトリガと同じ動作をさせたい場合はCOMPATIBLEを指定します。

バージョン09-50より前のHiRDBから,09-50以降のHiRDBにバージョンアップする場合の注意事項を次に示します。

  • トリガを再定義する場合で,09-50より前のHiRDBでFOR UPDATE EXCLUSIVEを省略したトリガと同じ動作をさせたい場合は,次のどちらかの対処をしてください。

    ・ALTER TRIGGER又はALTER ROUTINEでトリガのSQLオブジェクトを再作成してください。

    ・トリガを削除し,CREATE TRIGGERでトリガを再定義する場合は,COMPATIBLEを指定して再定義してください。

このオペランドと,ISOLATIONデータ保証レベルの関係から決まるFOR UPDATEの排他オプションを次に示します。

ISOLATION データ保証レベル

FOR UPDATE EXCLUSVIE

FOR UPDATE COMPATIBLE

0

WITH EXCLUSIVE LOCK

WITHOUT LOCK WAIT

1

WITH EXCLUSIVE LOCK

WITHOUT LOCK WAIT

2

WITH EXCLUSIVE LOCK

WITH EXCLUSIVE LOCK

《クライアント環境定義との関係》

CREATE TRIGGERに対して,PDISLLVL,PDFORUPDATEEXLOCKの指定は無効となります。

《SQLとの関係》

手続き中のSQL文に排他オプションを指定している場合はSQLコンパイルオプションで指定するデータ保証レベル,FOR UPDATE EXCLUSIVE,及びFOR UPDATE COMPATIBLEから仮定する排他オプションよりSQL文に指定した排他オプションが優先されます。

《システム定義との関係》

データ保証レベルを省略すると,pd_isolation_levelオぺランドの指定値が仮定されます。pd_isolation_levelオぺランドについては,マニュアル「HiRDB システム定義」を参照してください。

データ保証レベルについては,マニュアル「HiRDB UAP開発ガイド」を参照してください。

〔OPTIMIZE LEVEL SQL最適化オプション〔,SQL最適化オプション〕…〕

データベースの状態を考慮して,最も効率的なアクセスパスを決定するための最適化の方法を指定します。

SQL最適化オプションの指定値及びその内容については,マニュアル「HiRDB UAP開発ガイド」の「PDSQLOPTLVL」を参照してください。

SQL最適化オプションは,識別子(文字列)で指定する方法と,数値で指定する方法がありますが,通常時は識別子で指定する方法をお勧めします。

識別子で指定する場合:
OPTIMIZE LEVEL "識別子"〔,"識別子"〕…

<指定例>

  • ネストループジョイン優先とグループ分け高速化処理を適用する場合

    OPTIMIZE LEVEL "PRIOR_NEST_JOIN","RAPID_GROUPING"

  • すべての最適化を適用しない場合

    OPTIMIZE LEVEL "NONE"

<規則>

  1. 識別子は一つ以上指定してください。

  2. 識別子を二つ以上指定する場合は,コンマ(,)で区切ってください。

  3. すべての最適化を適用しない場合は,識別子に"NONE"を指定してください。ただし,同時に"NONE"以外の識別子を指定すると,"NONE"は無効になります。

  4. 識別子は大文字及び小文字で指定できます。

  5. 同じ識別子を二つ以上指定しても,一つ指定したものとみなされますが,なるべく同じ識別子は指定しないようにしてください。

数値で指定する場合:
OPTIMIZE LEVEL 符号なし整数〔,符号なし整数〕…

<指定例>

  • 複数のSQLオブジェクト作成,ANDの複数インデクス利用の抑止,及び複数インデクス利用の強制を適用する場合

    符号なし整数をコンマで区切って指定する場合:

    OPTIMIZE LEVEL 4,10,16

    符号なし整数の和を指定する場合:

    OPTIMIZE LEVEL 30

  • 既に14(4+10)を指定していて,新たに16を追加する場合

    OPTIMIZE LEVEL 14,16

  • すべての最適化を適用しない場合

    OPTIMIZE LEVEL 0

<規則>

  1. バージョン06-00より前のHiRDBから,バージョン06-00以降のHiRDBにバージョンアップする場合,バージョン06-00より前の合計値指定も有効となります。最適化オプションを変更する必要がない場合は,バージョン06-00以降のHiRDBにバージョンアップしたときにこのオペランドの指定値を変更する必要はありません。

  2. 符号なし整数は一つ以上指定してください。

  3. 符号なし整数を二つ以上指定する場合は,コンマ(,)で区切ってください。

  4. すべての最適化を適用しない場合は,符号なし整数に0を指定してください。ただし,同時に0以外の識別子を指定すると,0は無効になります。

  5. 同じ符号なし整数を二つ以上指定しても,一つ指定したものとみなされますが,なるべく同じ符号なし整数は指定しないようにしてください。

  6. 複数の最適化方法を指定する場合,その符号なし整数の和を指定することもできます。ただし,同じ最適化方法の値は二つ以上足さないでください(足した結果が別の最適化方法とみなされることもあるため)。

  7. 複数の最適化方法の値を足して指定する場合,どの最適方法を指定しているのか分かりにくくなるため,コンマで区切って指定する方法をお勧めします。また,既に複数の最適化方法の値を足して指定している場合で,新たに別の最適化方法が必要になったときは,追加する値をコンマで区切って後ろに指定できます。

《システム定義との関係》
  1. SQL最適化オプションを省略すると,システム定義のpd_optimize_levelオぺランドの指定値が仮定されます。pd_optimize_levelオペランドについては,マニュアル「HiRDB システム定義」を参照してください。

  2. システム定義のpd_floatable_besオペランド,又はpd_non_floatable_besオペランドを指定している場合,「フロータブルサーバ対象拡大(データ取り出しバックエンドサーバ)」及び「フロータブルサーバ対象限定(データ取り出しバックエンドサーバ)」の指定は無効となります。

  3. システム定義のpd_indexlock_modeオペランドにKEYを指定している場合(インデクスキー値排他の場合),「更新SQLの作業表作成抑止」の指定は無効になります。

《クライアント環境定義との関係》

CREATE TRIGGERに対して,PDSQLOPTLVLの指定は無効となります。

《SQLとの関係》

SQL文中にSQL最適化指定を指定している場合は,SQL最適化オプションよりもSQL最適化指定が優先されます。SQL最適化指定については,「SQL最適化指定」を参照してください。

〔ADD OPTIMIZE LEVEL SQL拡張最適化オプション〔,SQL拡張最適化オプション〕…〕

データベースの状態を考慮して,最も効率的なアクセスパスを決定するための最適化の方法を指定します。

SQL拡張最適化オプションの指定値及びその内容については,マニュアル「HiRDB UAP開発ガイド」の「PDADDITIONALOPTLVL」を参照してください。

SQL拡張最適化オプションは,識別子(文字列)で指定する方法と,数値で指定する方法があります。

識別子で指定する場合:
ADD OPTIMIZE LEVEL "識別子"〔,"識別子"〕…

<指定例>

  • 「コストベース最適化モード2の適用」及び「ハッシュジョイン,副問合せのハッシュ実行」を適用する場合

    ADD OPTIMIZE LEVEL "COST_BASE_2","APPLY_HASH_JOIN"

  • すべての最適化を適用しない場合

    ADD OPTIMIZE LEVEL "NONE"

<規則>

  1. 識別子は一つ以上指定してください。

  2. 識別子を二つ以上指定する場合は,コンマ(,)で区切ってください。

  3. すべての最適化を適用しない場合は,識別子に"NONE"を指定してください。

  4. 識別子は大文字及び小文字で指定できます。

  5. 同じ識別子を二つ以上指定しても,一つ指定したものとみなされますが,なるべく同じ識別子は指定しないようにしてください。

数値で指定する場合:
ADD OPTIMIZE LEVEL 符号なし整数〔,符号なし整数〕…

<指定例>

  • 「コストベース最適化モード2の適用」及び「ハッシュジョイン,副問合せのハッシュ実行」を適用する場合

    ADD OPTIMIZE LEVEL 1,2

  • すべての最適化を適用しない場合

    ADD OPTIMIZE LEVEL 0

<規則>

  1. 符号なし整数は一つ以上指定してください。

  2. 符号なし整数を二つ以上指定する場合は,コンマ(,)で区切ってください。

  3. すべての最適化を適用しない場合は,符号なし整数に0を指定してください。

  4. 同じ符号なし整数を二つ以上指定しても,一つ指定したものとみなされますが,なるべく同じ符号なし整数は指定しないようにしてください。

《システム定義との関係》

SQL拡張最適化オプションを省略すると,システム定義のpd_additional_optimize_levelオぺランドの指定値が仮定されます。pd_additional_optimize_levelオペランドについては,マニュアル「HiRDB システム定義」を参照してください。

《クライアント環境定義との関係》

CREATE TRIGGERに対して,PDADDITIONALOPTLVLの指定は無効となります。

《SQLとの関係》

SQL文中にSQL最適化指定を指定している場合は,SQL最適化オプションよりもSQL最適化指定が優先されます。SQL最適化指定については,「SQL最適化指定」を参照してください。

〔SUBSTR LENGTH 文字の最大長〕

1文字を表現する最大バイト数を指定します。

文字の最大長に指定できる値は,3〜6(pdntenvコマンド(UNIX版の場合はpdsetupコマンド)で文字コード種別にutf-8_ivsを指定した場合は3〜10)です。

pdntenvコマンド(UNIX版の場合はpdsetupコマンド)で文字コード種別にutf-8,又はutf-8_ivsを指定した場合にだけ有効となり,スカラ関数SUBSTRの結果の長さに影響します。SUBSTRについては,「SUBSTR」を参照してください。

《システム定義との関係》

SUBSTR LENGTHを省略すると,システム定義のpd_substr_lengthオぺランドの指定値が仮定されます。pd_substr_lengthオペランドについては,マニュアル「HiRDB システム定義」を参照してください。

《クライアント環境定義との関係》

CREATE TRIGGERに対して,PDSUBSTRLENの指定は無効となります。PDSUBSTRLENについては,マニュアル「HiRDB UAP開発ガイド」を参照してください。

《pdntenvコマンド又はpdsetupコマンドで指定した文字コード種別との関係》

文字コード種別にutf-8,又はutf-8_ivsを指定した場合だけ有効となります。

そのほかの文字コード種別の場合は,構文チェックだけ行い,指定を無視します。

(i) WITH PROGRAM

トリガ定義時に,そのトリガを定義する表を使用し,次のどれかの条件を満たす手続き,及びトリガの有効なSQLオブジェクトがあれば,そのSQLオブジェクトを無効にする場合に指定します。

  • トリガ契機がINSERTの場合,トリガを定義する表に対して行を挿入する手続き,及びトリガ

  • トリガ契機がUPDATEの場合,トリガを定義する表に対して行を更新する手続き,及びトリガ

  • トリガ契機がDELETEの場合,トリガを定義する表に対して行を削除する手続き,及びトリガ

バージョン07-00より前のHiRDBでSQLオブジェクトを作成した関数及び手続きは,上記の条件を満たしていなくてもすべて無効にします。

(5) 共通規則

  1. トリガを定義すると,トリガ動作手続きと呼ばれる手続きのSQLオブジェクトが作成され,データディクショナリLOB用RDエリアに格納されます。このため,トリガを定義するためには,あらかじめデータディクショナリLOB用RDエリアに十分な容量を確保しておく必要があります。データディクショナリLOB用RDエリアの容量の見積もりについては,マニュアル「HiRDB システム導入・設計ガイド」を参照してください。

  2. トリガ動作手続きのルーチン識別子は,次のような名称となります。なお,長さは22バイトです。

    '(TRIGyyyymmddhhmmssth)'

    yyyymmddhhmmssth:トリガ定義時のタイムスタンプ(100分の1秒単位)

  3. トリガ動作手続きの特定名は,〔認可識別子.〕トリガ動作手続きのルーチン識別子と同じです。トリガ動作手続きのルーチン識別子は,ディクショナリ表SQL_TRIGGERSのSPECIFIC_NAME列に格納されます。

  4. トリガを定義するユーザは,トリガSQL文を実行するために必要な権限を保持している必要があります。トリガを定義したユーザがその権限を保持しているかどうかは,トリガの定義時及び実行時にチェックされます。

  5. WITH PROGRAMを省略した場合,トリガを定義する表を使用し,SQLオブジェクトを変更する必要のある手続き,及びトリガの有効なSQLオブジェクトがあれば,そのトリガは定義できません。

  6. ALTER TRIGGER又はALTER ROUTINEでSQLコンパイルオプションを指定する場合,SQLオブジェクトを再作成するトリガの元のCREATE TRIGGERに,SQLコンパイルオプションを反映してできるSQLは,SQLの最大長を超えないようにしてください。

  7. 実行中のSQLオブジェクトが無効になる場合,Java手続き中からCREATE TRIGGERは実行できません。

(6) トリガを引き起こすSQLを実行するときの規則

  1. トリガは,指定したトリガ契機(INSERT文,UPDATE文,又はDELETE文)でだけ発生します。PURGE TABLE文,データベース作成ユティリティ,データベース再編成ユティリティ,及びRDエリアの再初期化などでは動作しません。

  2. トリガの実行順序を次に示します。

    [図データ]

  3. トリガ動作時期,トリガ契機,及びトリガの動作単位(文単位,又は行単位)が同じトリガを複数定義している場合は,定義した順番(SQL_TRIGGERS表のCREATE_TIME列の値の順番)にトリガ動作を実行します。

  4. トリガ実行時にエラーが発生した場合,そのトランザクションは無効となります(暗黙的ロールバックを引き起こします)。また,トリガを引き起こすSQLの実行時,1回でもトリガが実行された後でエラーが発生すると,そのエラーがトリガ実行時かどうか,又はトランザクションを無効にするかどうかに関係なく,そのトランザクションを無効にします。ただし,WITHOUT ROLLBACKを指定して定義した表については,行更新(追加,削除を含む)の処理完了後はロールバックしない場合があります。詳細は「CREATE TABLE(表定義)」のWITHOUT ROLLBACKの規則を参照してください。

  5. トリガを引き起こすSQLを実行するユーザは,トリガSQL文を実行するために必要な権限を保持している必要はありません。

  6. トリガSQL文中のSQLを契機として,ほかのトリガを実行することもできます(トリガのネスト)。ただし,ネストして動作するのは16段目のトリガまでで,16段目のトリガでほかのトリガを引き起こす操作が発生すると,エラーになります。

  7. トリガ契機にUPDATEを指定した行単位トリガは,その更新対象の行に対して1回だけ実行されます。トリガがネストして起動し,その延長で再度同じトリガが起動する場合でも,実行されるのは最初の1回だけです。

  8. UPDATEトリガが定義されている表に対して次の指定はできません。

    • 新値相関名を指定したUPDATEトリガを定義した表に対する,コンポネント指定を使用した更新

    • UPDATEトリガを定義した表に対する,連結演算を使用したBLOB型,又は定義長が32,001バイト以上のBINARY型の更新

  9. 行単位AFTERトリガを引き起こすSQLの副問合せ中で,トリガ動作又はその延長で更新される表を参照する場合,その副問合せには外への参照を含めないようにしてください。

(7) 留意事項

  1. CREATE TRIGGERは,OLTP下のX/Openに従ったUAPから指定できません。

  2. トリガSQL文に更新系SQL(UPDATE文,DELETE文,又はINSERT文)を指定する場合,指定した更新系SQLの実行時に次のようなSQLエラーになることがあります。

    • 更新系SQLを指定したFOR EACH ROWのトリガを実行するSQL中に,更新系SQLで指定した表が含まれている

    • 更新系SQLを指定したFOR EACH ROWのトリガを実行するFOR EACH ROWのトリガ定義(複数のトリガ定義がネストする場合も含む)中に,更新系SQL中に指定した表が含まれている

    このような場合は,システム定義でインデクスキー値無排他を指定するか,又はトリガ定義を変更してください。

  3. トリガSQL文に更新系SQLを指定する場合,指定した更新系SQLの実行中にSQLの検索に影響を与えることがあります。実行中のSQLの検索に影響させないようにするためには,更新系SQLが,実行中のSQLの検索条件に合致しないように,探索条件やデータを工夫する必要があります。特に,トリガ定義が入れ子になっている場合に注意してください。

  4. WITH PROGRAMを指定して手続き,及びトリガの有効なSQLオブジェクトを無効にした場合,ディクショナリ表SQL_ROUTINE_RESOURCES中から無効となった手続き,及びトリガに関する行は削除されます。

  5. WITH PROGRAMを指定して無効にした手続き,及びトリガのSQLオブジェクトを実行するためには,ALTER ROUTINE,ALTER PROCEDURE,又はALTER TRIGGERを実行して,手続き,及びトリガのSQLオブジェクトを再作成しておく必要があります。

  6. トリガ中のトリガSQL文のデータ保証レベル,SQL最適化オプション,SQL拡張最適化オプション,及び文字の最大長は,トリガの定義時,又は変更時の指定で決まり,トリガ動作実行時のシステム定義やクライアント環境定義の影響を受けません。

  7. ON 〔認可識別子.〕表識別子で指定した表を基表とするビュー表に対しても,トリガ契機に指定した操作を実行すれば,トリガ動作は実行されます。

  8. トリガのSQLオブジェクトが無効な場合,そのトリガを定義した表を使用し,次のどれかに該当するSQLを実行すると,トリガ動作条件の真偽に関係なくエラーとなります。また,トリガのSQLオブジェクトのインデクスが無効な場合は,そのトリガを定義した表を使用し,次のどれかに該当するSQLを実行すると,トリガ動作条件が真のときにエラーとなります。

    • トリガ契機がINSERTの場合,トリガを定義した表に対して行を挿入するINSERT文

    • トリガ契機がUPDATEの場合,トリガを定義した表に対して行を更新するUPDATE文

    • トリガ契機がDELETEの場合,トリガを定義する表に対して行を削除するDELETE文

  9. トリガがネストしている場合,性能が劣化する場合があります。できるだけネストはしないようにしてください。

  10. ネストするトリガを作成する場合,先頭のトリガから作成すると,ネストするトリガ作成時にエラーとなります。また,WITH PROGRAM指定をすると,ネストするトリガは作成できますが,先頭のトリガが無効状態となります。このため,ネストするトリガを作成する場合は,ネストの末端のトリガから順番に作成してください。

(8) 使用例

CREATE TRIGGERの使用例では,在庫表(ZAIKO)のほかに,在庫履歴表(RZAIKO),広島在庫表,仙台在庫表を使用します。広島在庫表と仙台在庫表は,在庫表と同じ構成です。在庫履歴表の構成は次のとおりです。

[図データ]

  1. 在庫表(ZAIKO)に行が挿入された後,挿入された行の情報を在庫履歴表(RZAIKO)に挿入するトリガ(INSERTTRIG1)を定義します。

      CREATE TRIGGER INSERTTRIG1
        AFTER INSERT ON ZAIKO
        REFERENCING NEW ROW X1
        FOR EACH ROW
        INSERT INTO RZAIKO
          VALUES(X1.SCODE,NULL,X1.ZSURYO,CURRENT_DATE,CURRENT_TIME)
  2. 在庫表(ZAIKO)の数量(ZSURYO)が更新された後,更新前後の値を在庫履歴表(RZAIKO)に挿入するトリガ(INSERTTRIG2)を定義します。

      CREATE TRIGGER INSERTTRIG2
        AFTER UPDATE OF ZSURYO ON ZAIKO
        REFERENCING NEW ROW X1 OLD ROW Y1
        FOR EACH ROW
        INSERT INTO RZAIKO
          VALUES(Y1.SCODE,Y1.ZSURYO,X1.ZSURYO,CURRENT_DATE,CURRENT_TIME)
  3. 在庫表(ZAIKO)から行が削除された後,削除された行の情報を在庫履歴表(RZAIKO)に挿入するトリガ(INSERTTRIG3)を定義します。

      CREATE TRIGGER INSERTTRIG3
        AFTER DELETE ON ZAIKO
        REFERENCING OLD ROW Y1
        FOR EACH ROW
        INSERT INTO RZAIKO
          VALUES(Y1.SCODE,Y1.ZSURYO,NULL,CURRENT_DATE,CURRENT_TIME)
  4. トリガ動作にルーチン制御SQL(複合文)を使用します。在庫表(ZAIKO)が更新された後,その更新内容を広島在庫表,及び仙台在庫表に反映するトリガ(UPDATELOCAL)を定義します。なお,複合文を使用しない場合は,在庫表の更新を契機にしたトリガを二つ定義しなければなりません。

      CREATE TRIGGER UPDATELOCAL 
        AFTER UPDATE OF ZSURYO ON ZAIKO
        REFERENCING NEW ROW X1 OLD ROW Y1
        BEGIN
          UPDATE 広島在庫表 SET ZSURYO=X1.ZSURYO WHERE SCODE=Y1.SCODE;
          UPDATE 仙台在庫表 SET ZSURYO=X1.ZSURYO WHERE SCODE=Y1.SCODE;
        END
  5. トリガ動作にルーチン制御SQL(代入文)を使用します。在庫表(ZAIKO)に挿入される行に対し,商品コード(SCODE)が101M,201M,又は301Mの場合は挿入される単価(TANKA)に5,000円を加算した金額を,商品コード(SCODE)が101M,201M,又は301M以外の場合は挿入される単価を1.2倍にした金額を新しく単価に設定するトリガ(SETTANKA)を定義します。

      CREATE TRIGGER SETTANKA
        BEFORE INSERT ON ZAIKO
        REFERENCING NEW ROW AS X1
        FOR EACH ROW
        SET X1.TANKA=CASE X1.SCODE WHEN '101M' THEN X1.TANKA+5000
            WHEN '201M' THEN X1.TANKA+5000
            WHEN '301M' THEN X1.TANKA+5000
            ELSE X1.TANKA * 1.2
          END
  6. トリガ動作にSQL診断文(SIGNAL文)を使用します。在庫表(ZAIKO)の行を削除する前にSIGNAL文でエラーを発生させ,在庫表からの行の削除を抑止するトリガ(SIGNALTRIG)を定義します。

      CREATE TRIGGER SIGNALTRIG
        BEFORE DELETE ON ZAIKO
        SIGNAL SQLSTATE '99001'