トリガを作成します。
Synopsis
CREATE TRIGGER name BEFORE event ORDER integer ON table REFERENCING alias action
CREATE TRIGGER name AFTER event ORDER integer ON table REFERENCING alias action
CREATE TRIGGER コマンドの実行には特権が必要です。
CREATE TRIGGER を使用する前に、%CREATE_TRIGGER 特権を得る必要があります。この設定を行わないと、SQLCODE -99 (特権違反) になります。適切な付与特権を持っていれば、
GRANT コマンドを使用して、%CREATE_TRIGGER 特権を割り当てることができます。埋め込み SQL では、以下のように $SYSTEM.Security.Login メソッドを使用して適切な特権を持ったユーザとしてログインできます。
DO $SYSTEM.Security.Login("_SYSTEM","SYS")
&sql( )
トリガ名にはテーブル名と同様の識別子要件があります。しかし一意性の要件は異なります。トリガ名はスキーマ内のテーブルに対して一意である必要があります。したがって、スキーマ内の異なるテーブルを参照しているトリガの名前が同じ場合もあります。トリガとそのトリガが関連するテーブルは同じスキーマ内に存在している必要があります。同じスキーマ内では、トリガとテーブルに同じ名前を使用できません。トリガの名前付け規約に違反すると、
CREATE TRIGGER の実行時に SQLCODE -400 エラーが発生します。
トリガ名は、修飾、未修飾のどちらでもかまいません。修飾されたトリガ名は次のようになります。
トリガ名が未修飾の場合、トリガ・スキーマ名は既定で
table のスキーマと同じになります。どちらも未修飾であれば、システムの既定スキーマが使用されます。トリガ名を修飾する場合は、トリガ・スキーマ名をテーブル・スキーマ名と同じにする必要があります。テーブル・スキーマ名が指定されていない場合は、トリガ・スキーマ名が使用されます。スキーマ名が一致しないと SQLCODE -366 エラーになります。これはトリガ名とテーブル名の両方が修飾されていて、異なるスキーマ名を指定しているときにのみ起こります。
トリガ名は、
識別子の規則に従い、以下のような制約を受けます。既定のトリガ名は、簡単な識別子です。トリガ名は 128 文字を超えることはできません。トリガ名は、大文字と小文字が区別されません。
Caché はトリガ名 (SQLNAME) を使用して、対応する Caché 識別子を生成します。Caché 識別子には英数字 (文字および数字) のみが使用され、その長さは最大 25 文字です。この Caché 識別子名を生成するために、Caché は最初にトリガ名から句読点を削除し、次に 25 文字 (未満) の一意の識別子を生成します。その際、トリガ名の一意性を維持するために、必要に応じて最後の文字を数字に置き換えます。トリガの名前を付ける際には、この名前生成に伴う以下の制約について考慮する必要があります。
-
トリガ名には、最低でも 1 文字を含める必要があります。トリガ名の先頭の文字または最初の句読点に続く文字は、数字以外の文字にする必要があります。
-
Caché は Unicode システムで、16 ビット (ワイド) 文字のトリガ名をサポートします。
$ZNAME テストに合格した文字は、有効な文字です。
-
生成された Caché の名前には句読点が含まれないため、句読点のみが異なるトリガ名の作成は可能ですが、お勧めできません。
-
トリガ名は 25 文字よりも大幅に長くすることができますが、最初の 25 の英数文字が異なるようにトリガ名を作成すると処理がはるかに容易になります。
INSERT として指定されたトリガは、指定されたテーブルに行が挿入されたときに引き出されます (実行されます)。DELETE として指定されたトリガは、指定されたテーブルから行が削除されたときに引き出されます。UPDATE として指定されたトリガは、指定されたテーブルの行が更新されたときに引き出されます。
UPDATE OF として指定されたトリガは、指定されたテーブルの行で 1 つ以上の指定された列が更新されたときにのみ、引き出されます。列名はコンマ区切りのリストで指定します。列名は任意の順序で指定できますが、重複して使用することはできません。重複していると、コンパイル時に SQLCODE -58 エラーが発生します。UPDATE OF 節はトリガ・コード LANGUAGE が SQL (既定) の場合のみ有効です。
BEFORE トリガが引き出される (実行される) のは、指定した
event の実行前ですが、
event の検証
よりも後です。例えば、
DELETE 文が指定の行に対して有効で、
DELETE の実行 (外部キー参照の整合性チェックも含む) に必要な特権がプロセスに与えられている場合にのみ、BEFORE DELETE トリガが引き出されます。プロセスが指定の
event を実行できない場合、
event に対してエラー・コードが発行され、BEFORE トリガは引き出されません。
ORDER 節は、1 つのテーブルに同じタイミングとイベントを持つトリガが複数あるときに、トリガが引き出される順番を決定します。例えば、2 つの AFTER DELETE トリガのような場合です。ORDER の整数値が最小のトリガが最初に実行され、その後は、次に高い整数値を持つトリガが順次実行されます。ORDER 節が指定されない場合は、ORDER 値に 0 (ゼロ) が割り当てられてトリガが生成されます。したがって、ORDER 節を持たないトリガは、必ず ORDER 節を持つトリガの前に実行されます。
複数のトリガに同じ ORDER 値を割り当てることができます。また、ORDER が 0 (明示的または暗黙的) のトリガを複数作成することもできます。タイミング、イベント、および順序が同じ複数のトリガは、任意の順序でまとめて実行されます。
以下の例は、ORDER 値がどのように機能するかを示します。以下のすべての
CREATE TRIGGER 文は、同じイベントによって引き出されるトリガを作成します。
CREATE TRIGGER TrigA BEFORE DELETE ON doctable
INSERT INTO TLog VALUES ('doc deleted');
-- Assigned ORDER=0
CREATE TRIGGER TrigB BEFORE DELETE ORDER 4 ON doctable
INSERT INTO TReport VALUES ('doc deleted')
-- Specified as ORDER=4
CREATE TRIGGER TrigC BEFORE DELETE ORDER 2 ON doctable
INSERT INTO Ttemps VALUES ('doc deleted')
-- Specified as ORDER=2
CREATE TRIGGER TrigD BEFORE DELETE ON doctable
INSERT INTO Tflags VALUES ('doc deleted')
-- Also assigned ORDER=0
これらのトリガは、(TrigA または TrigD)、TrigC、TrigB の順に実行されます。TrigA と TrigD は同じ ORDER 値となるので、任意の順序で実行されます。
REFERENCING 節では、行の元の値、新しい値、またはその両方に対してエイリアスを指定できます。元の値とは、UPDATE または DELETE トリガのトリガ動作が実行される前の行の値のことです。新しい値とは、UPDATE または INSERT トリガのトリガ動作が実行された後の行の値のことです。UPDATE トリガの場合は、以下のようにして、元の行値と新しい値の両方にエイリアスを指定できます。
REFERENCING OLD ROW AS oldalias NEW ROW AS newalias
キーワードの ROW と AS は省略可能です。したがって、同じ節を以下のように指定することもできます。
REFERENCING OLD oldalias NEW newalias
INSERT 前の元の値や DELETE 後の新しい値を参照することには、意味がありません。それらを参照すると、コンパイル時に SQLCODE -48 が返されます。
REFERENCING 節は
action プログラム・コードが SQL の場合にのみ、使用できます。LANGUAGE OBJECTSCRIPT 節とともに REFERENCING 節を指定すると、SQLCODE -49 エラーになります。
-
-
オプションの WHEN 節。WHEN 節は、WHEN キーワードとその後の括弧で囲まれた検索条件 (単純または複雑な) から成ります。検索条件が真に評価されると、トリガが実行されます。WHEN 節は、LANGUAGE が SQL の場合にのみ使用できます。
-
オプションの LANGUAGE 節。LANGUAGE SQL または LANGUAGE OBJECTSCRIPT を指定できます。既定は LANGUAGE SQL です。
-
トリガが引かれたときに実行されるユーザ記述のコードです。
LANGUAGE SQL の場合、既定でトリガ文は SQL プロシージャ・ブロックです。SQL プロシージャ・ブロックは、1 つの SQL プロシージャ文とその後のセミコロン、またはキーワード BEGIN で始まりキーワード END で終わる 1 つ以上の SQL プロシージャ文と各文の後のセミコロンから成ります。
トリガ動作はアトミックで、完全に適用されるかまったく適用されないかのどちらかです。これに
COMMIT 文または
ROLLBACK 文を含めることはできません。キーワード BEGIN ATOMIC は、キーワード BEGIN と同義です。
LANGUAGE SQL の場合、
CREATE TRIGGER 文はオプションで REFERENCING 節、WHEN 節、および/または UPDATE OF 節を含むことができます。UPDATE OF 節は、トリガに指定された 1 つ以上の列で
UPDATE が実行されるときにのみ、トリガを実行することを指定します。LANGUAGE OBJECTSCRIPT の
CREATE TRIGGER 文では、これらの節を含むことができません。
SQL トリガ・コードは埋め込み SQL として実行されます。Caché は自動的に、トリガ・コード内で使用されているすべての変数をリセット (NEW) します。各 SQL 文の実行後に、Caché は SQLCODE をチェックします。エラーが発生すると、Caché は %ok 変数に 0 をセットし、トリガ・コードの処理および関連する
INSERT、
UPDATE、または
DELETE を中止してロールバックします。
LANGUAGE OBJECTSCRIPT の場合、
CREATE TRIGGER 文は REFERENCING 節、WHEN 節、または UPDATE OF 節を含むことができません。これらの SQL 限定である節を LANGUAGE OBJECTSCRIPT とともに指定すると、それぞれコンパイル時に SQLCODE エラーの -49、-57、または -50 が発生します。
LANGUAGE OBJECTSCRIPT の場合、トリガ文は、中括弧で囲まれた 1 つ以上の Caché ObjectScript 文からなるブロックです。こうしたトリガ・コードでラベルを指定するには、ラベル行の先頭にコロンを付けて、その行が最初の列で始まることを示します。Caché はコロンを削除して、残りの行をラベルとして処理します。
Note:
ラベル用のコロン接頭語の使用は、
ホスト変数参照用のコロン接頭語の使用よりも優先されます。この競合を回避するために、埋め込み SQL トリガ・コード行の先頭にホスト変数参照を記述しないことをお勧めします。トリガ・コード行の先頭にホスト変数参照を記述する必要がある場合は、二重のコロン接頭語を使用することで、それがホスト変数でありラベルでないことを明示してください。
Caché ObjectScript で記述するトリガ・コードには、{
fieldname} で指定するフィールド参照を含めることができます。ここで、
fieldname は現在のテーブルの既存フィールドを指定します。中括弧内に空白スペースは許可されません。現在のフィールドは、{*} のようにアスタリスクを使用して指定できます。
UPDATE トリガ・コードでは、
fieldname の後に *N、*O、または *C を続けることで、変更フィールドのデータ値の処理方法を指定できます。{
fieldname*N} は、指定された変更が実行された後の新しいフィールド値を返します。これが既定です。{
fieldname*O} は、指定された変更が実行される前の元のフィールド値を返します。{
fieldname*C} は、フィールド値が変更されたかどうかを示すブーリアン値 (変更の場合は 1、未変更の場合は 0) を返します。
また、Caché ObjectScript で記述するトリガ・コードには、擬似フィールド参照変数の {%%CLASSNAME}、{%%CLASSNAMEQ}、{%%TABLENAME}、および {%%ID} を含めることもできます。擬似フィールドは、クラスのコンパイル時に特定の値に変換されます。{%%CLASSNAME} と {%%CLASSNAMEQ} は、ともに SQL テーブル定義を投影するクラスの名前に変換されます。{%%CLASSNAME} は引用符なし文字列を返し、{%%CLASSNAMEQ} は引用符付き文字列を返します。{%%TABLENAME} はテーブルの完全修飾名に変換され、引用符付き文字列を返します。{%%ID} は RowID 名に変換されます。この参照は、RowID フィールドの名前がわからないときに有用です。これらの擬似フィールド・キーワードは、すべて大文字と小文字が区別されません。
%ok 変数を 0 に設定することで、トリガ・コードからエラーを発行できます。この設定によって、実行時エラーを生成し、トリガの実行が中止されます。また、トリガ・コードでは
%msg 変数に実行時エラーの起きた節を記述する文字列を設定することもできます。
トリガおよびそのトリガが起動するイベントは、単一行ベースでアトミック処理として実行されます。つまり、以下のように処理されます。
整合性が維持されるのは、現在の行の操作のみであることに注意してください。アプリケーション・プログラムは、トランザクション処理文を使用して、複数行での操作も含めてデータの整合性の問題に対処する必要があります。
トリガはアトミック処理であるため、コミットやロールバックのようなトランザクション文は、トリガ・コード内ではコーディングできません。
致命的なランタイム・エラーによってデータベース操作が失敗すると、Caché は SQLCODE -415 エラーを発行します。トリガ処理が失敗すると、Caché は失敗したトリガのタイプにより SQLCODE エラー・コードの -130 から -135 のうちの 1 つを発行します。トリガ・コード内で
%ok 変数を 0 に設定することで、トリガを失敗させることができます。また、
%msg 変数にトリガの失敗時に返すメッセージを含む文字列を設定することもできます。
以下の埋め込み SQL の例は、SQL 挿入トリガを作成します。
DO $SYSTEM.Security.Login("_SYSTEM","SYS")
&sql(CREATE TABLE TestDummy (
TESTNUM INT NOT NULL,
FIRSTWORD CHAR (30) NOT NULL,
LASTWORD CHAR (30) NOT NULL,
CONSTRAINT TestDummyPK PRIMARY KEY (TESTNUM))
)
WRITE !,"SQL table code is: ",SQLCODE
&sql(CREATE TRIGGER TrigTestDummy AFTER INSERT ON TestDummy
BEGIN
INSERT INTO LogFile VALUES ('INSERT into TestDummy');
END)
WRITE !,"SQL trigger code is: ",SQLCODE
以下の例は AFTER INSERT トリガを作成します。
CREATE TRIGGER Trigger_1 AFTER INSERT ON Table_1
REFERENCING NEW ROW AS new_row
BEGIN
INSERT INTO Log_Table VALUES ('INSERT into Table_1');
INSERT INTO New_Log_Table VALUES
('INSERT into Table_1', new_row.ID);
END
CREATE TRIGGER Trigger_2 AFTER INSERT ON Table_1
REFERENCING NEW ROW AS new_row
BEGIN
INSERT INTO Log_Table VALUES (new_row.Category);
END