随時翻訳を続けています。
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 ステートメントを使って 削除します。