面倒臭がりなプログラマーにとって、トリガーは素晴らしい機能です。トリガーを作成すると、最小限の労力で多くのことを自動化することができます。トリガーは、INSERT、DELETE、UPDATEのSQL文で実行されます。一般的には、データの参照整合性や矛盾を解決するために使用されます。
例えば、請求書データを削除する時に、関連したすべての請求書を削除する、といった具合です。今回のアプリケーションでは、3個のトリガーを作成します。TIMESTAMP型のフィールドに自動で値を入れるもの、そしてビューを更新するものです。
前者のトリガーをリスト3に掲載します。これは、tblresoucesテーブルにレコードが追加されたり、更新された場合に実行されます。プログラム側でwhenalteredフィールドを更新する必要がなく、現在の日時が自動的に追加されます。MySQLでいうTIMESTAMP型フィールドに近いものです。同様に、リスト3ではadd_date トリガーも作成しています。
リスト3
CREATE TRIGGER insert_resources
AFTER INSERT ON tblresources
BEGIN
UPDATE tblresources
SET whenaltered = DATETIME('NOW','LOCALTIME')
WHERE id = new.id;
END;
CREATE TRIGGER update_resources
AFTER UPDATE ON tblresources
BEGIN
UPDATE tblresources
SET whenaltered = DATETIME('NOW','LOCALTIME')
WHERE id = new.id;
END;
CREATE TRIGGER add_date AFTER INSERT ON tblresources
BEGIN
UPDATE tblresources
SET whenadded = DATE('NOW','LOCALTIME')
WHERE id = new.id;
END;
CREATE TRIGGER delete_link
INSTEAD OF DELETE ON specific_link
FOR EACH ROW
BEGIN
DELETE FROM tblresources
WHERE id = old.id;
END;
リンクを追加した日付を格納することで、新しいリンクをハイライト表示させるためです。また、ビューに対してトリガーを使うことで、ビューのUPDATEができるようになります。逆にいうと、トリガーを使わない場合はビューを更新できません。トリガーが関連づけられていないビューの場合、削除をした場合には以下のような警告が表示されてしまいます。
Warning: SQLiteDatabase::query() [function.
query]: cannot
modify specific_link because it is a view ...
specifig_linkビューに作成されたリスト3のトリガーを見てみましょう。INSTEAD OF を使用することで、ビューからレコードを削除しようとした時に、tblresourcesテーブルから対応するレコードを削除するようになります。
このトリガーではオプションのFOR EACHROWを使用しています。FOR EACH STATEMENT句も一般的にはありますが、サポートされていません。
トリガーのWHERE句を見てみると直感的に理解しやすいかと思いますが、注意が必要です。new.idが新しくインサートされたレコードを特定するもので、old.id は削除されたレコードに対するもの、というのは明らかでしょう。
しかし、レコードがアップデートされた時はold.idでもnew.idでもかまわないのです。トリガーを使わなくてもプログラムで同じ動作は実装することができますが、トリガーは非常に便利です。トリガーはデータベースに内蔵されている機能なので、コマンドラインからデータベースにアクセスする時にも実行されます。
そのためトリガーを使用するとアプリケーション以外から修正が加えられても、データベースの整合性を保つことができます。
|