Third impact
最終更新: 2010-04-24
更新者: 00000001
SQLite翻訳文書セットの一部です。
随時翻訳を続けています。

CREATE TRIGGER

sql-statement ::= CREATE [TEMP | TEMPORARY] TRIGGER trigger-name [ BEFORE | AFTER ]
database-event ON [database-name .] table-name
trigger-action
sql-statement ::= CREATE [TEMP | TEMPORARY] TRIGGER trigger-name INSTEAD OF
database-event ON [database-name .] view-name
trigger-action
database-event ::= DELETE |
INSERT
|
UPDATE
|
UPDATE OF
column-list
trigger-action ::= [ FOR EACH ROW | FOR EACH STATEMENT ] [ WHEN expression ]
BEGIN
    
trigger-step ; [ trigger-step ; ]*
END
trigger-step ::= update-statement | insert-statement |
delete-statement | select-statement

CREATE TRIGGER ステートメントは、データベースのスキーマにトリガーを追加するために使います。 トリガーは、指定したデータベースイベント(database-event)が起こったとき自動的に 実行されるデータベース操作(trigger-action)です。

特定のデータベースのテーブルで DELETE、INSERT または UPDATE が起きた時、 あるいはひとつまたはそれ以上のテーブルの指定されたカラムが UPDATE で更新される時、 始動されるトリガーを指定できます。

現状の SQLite は、FOR EACH ROW トリガーのみをサポートし、 FOR EACH STATEMENT トリガーはサポートしません。 それ故、明示的な FOR EACH ROW の指定はオプションです。 FOR EACH ROW は、トリガーが始動すると挿入、更新、削除される データベースの行それぞれに対して trigger-steps として指定された SQL ステートメントが(WHEN 句に応じて)実行されることを意味します。

WHEN 句と trigger-steps の両方が、"NEW.column-name" と "OLD.column-name" という形式の参照を使って、挿入、削除、更新される行の要素に アクセスできます。 column-name は、トリガーが結びつくテーブルのカラム名です。 OLD と NEW リファレンスは、以下のような適切な trigger-event 上のトリガー内でのみ 使うことができます。

INSERT NEW リファレンスが通用します
UPDATE NEW と OLD リファレンスが通用します
DELETE OLD リファレンスが通用します

WHEN 句が与えられてる場合、trigger-steps として指定された SQL ステートメントが WHEN 句が真となる行に対してのみ実行されます。 WHEN 句が与えられない場合、SQL ステートメントがすべての行に対して実行されます。

関連する行の挿入、修正、除去に対して trigger-steps がいつ実行されるか、 trigger-time を指定することで決定します。

ON CONFLICT 句を UPDATE あるいは INSERT trigger-step の一部として 指定できます。 しかしながら、トリガーを作動させたステートメントの一部として ON CONFLICT 句が 指定されていた場合、その競合処理方針が代わりに使われます。

トリガーは、それらに関連付けられたテーブルがドロップされるとき、自動的に ドロップされます。

トリガーは、CREATE TRIGGER で INSTEAD OF を指定することによって、一般のテーブルと同様に view 上にも作ることができます。 一つ以上の ON INSERT、ON DELETE、ON UPDATE トリガーを view 上に定義した場合、 view 上でそれぞれ INSERT、DELETE、UPDATE を実行してもエラーにはなりません。 その後、view 上で INSERT、DELETE、UPDATE を実行すると関連するトリガーの作動を 引き起こします。 view の元となる実際のテーブルは、(トリガープログラムによって明示する場合を除いて) 修正されません。

カスタマーレコードが "customers" テーブルに格納され、注文レコードが "orders" テーブルに 格納されている場合を想定すると、以下のトリガーは、顧客が彼または彼女の住所を変更すると すべての関連する注文が書き換えられることを保証します。

CREATE TRIGGER update_customer_address UPDATE OF address ON customers 
  BEGIN
    UPDATE orders SET address = new.address WHERE customer_name = old.name;
  END;

インストールされたこのトリガーで、ステートメントを実行すると。

UPDATE customers SET address = '1 Main St.' WHERE name = 'Jack Jones';

その結果、以下が自動的に実行されます。

UPDATE orders SET address = '1 Main St.' WHERE customer_name = 'Jack Jones';

現状では、INTEGER PRIMARY KEY フィールドを持つテーブル上にトリガーを作ると、 奇妙な動作をすることに注意してください。 BEFORE トリガープログラムが、トリガーの引き金となるステートメントによって後に更新される 行の INTEGER PRIMARY KEY フィールドを 修正する場合、更新が起こりません。 これは、INTEGER PRIMARY KEY カラムの代わりに PRIMARY KEY カラムでテーブルを宣言することで 回避できます。

特別な SQL 関数である RAISE() を以下のような構文で trigger-program 内において使えます。

raise-function ::= RAISE ( ABORT, error-message ) |
RAISE ( FAIL,
error-message ) |
RAISE ( ROLLBACK,
error-message ) |
RAISE ( IGNORE )

trigger-program の実行中に、最初の3つの形式のうち一つが呼び出されると、 ON CONFLICT 処理(ABORT、FAIL、ROLLBACKのどれか)が実行され、 現在の問い合わせは終了します。 SQLITE_CONSTRAINT のエラーコードが、指定のエラーメッセージとともに ユーザーに返されます。

RAISE(IGNORE) が呼び出されると、現在のトリガープログラムの残りの部分、 実行用トリガープログラムを引き起こしたステートメント、そして、 後に続く実行予定のトリガープログラムが放棄されます。 データベースへの変更はロールバックされません。 トリガープログラムを実行させたステートメント自身がトリガープログラムの一部である場合、 そのトリガープログラムは次のステップの最初に実行を再開します。

トリガーは、DROP TRIGGER ステートメントを使って 削除します。

This page last modified on 2006/02/09 22:13:42
お知らせ
Wiki始めました。