TOP書籍連動> トリガー
SQLiteの高度な活用術
SQLiteの高度な活用術

第2回:最小限の労力で最大限の効果を得る技

著者:Peter Lavin   2006/4/4
前のページ  1  2
トリガー

   面倒臭がりなプログラマーにとって、トリガーは素晴らしい機能です。トリガーを作成すると、最小限の労力で多くのことを自動化することができます。トリガーは、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でもかまわないのです。トリガーを使わなくてもプログラムで同じ動作は実装することができますが、トリガーは非常に便利です。トリガーはデータベースに内蔵されている機能なので、コマンドラインからデータベースにアクセスする時にも実行されます。

   そのためトリガーを使用するとアプリケーション以外から修正が加えられても、データベースの整合性を保つことができます。


PHPでの実装

   今回の記事で扱うアプリケーションはオブジェクト指向を使用します。根っからの手続き型のプログラマーは投げ出したくなってしまうかもしれませんが、ほとんどのSQLiteのオブジェクト指向のメソッドは手続き型の関数と変わりありません。違うのは接頭辞としてのsqliteが外されて、命名規則が異なることくらいです。

   メソッドの引数についても手続き型の関数とほぼ同じです。違いは、オブジェクトそのものがリソースハンドルとなっているので、手続き型で必要なハンドルを指定しないということだけです。また、いくつかの関数は手続き型でのみ使用することができます。

   オブジェクト指向の考え方が常によいといわけではありませんが、SOAPクライアントを作成する場合などオブジェクト指向でなければならない時もあります。アプリケーションの特定の環境では、オブジェクト指向はより適したアプローチになると著者は考えています。しかし、これは人それぞれなので各人で自分がどうするべきなのかを判断するべきでしょう。

   PHPであらかじめ使用できるSQLiteのオブジェクトは、SQLiteのデータベース、バッファーされたもの、およびバッファーされていない結果セット、この3つです。この3つのクラスすべてを使用しますが、ここではデータベースのクラスに注目します。

前のページ  1  2


Peter Lavin
著者プロフィール
Peter Lavin
カナダ、トロントでWebデザイナ/Web開発者として働いています。現在、PHPのオブジェクト指向をテーマにした本を執筆しており、No Starch Press社より出版される予定です。


INDEX
第2回:最小限の労力で最大限の効果を得る技
  ビュー
トリガー