例えば、学生のデータを保存するテーブルがあるとしよう。このテーブルでは、新しい学生が追加されるたびにlast_modified(レコードが最後に変更された日付)フィールドを自動で更新したいんだ。このフィールドは、変更履歴を追跡したりデータ管理するのに大事だよ。
動作の流れはこんな感じ:
- テーブルに新しいレコードが追加されたら、
last_modifiedフィールドに自動で現在の日付と時刻が入る。 AFTER INSERTトリガーを使って、データ挿入が成功した後に動作させる。
トリガー用の関数を作る
まずはPL/pgSQLで関数を作る必要があるよ。この関数がテーブルのlast_modifiedフィールドを更新するんだ。関数はトリガー動作の必須要素で、トリガー自体は「何をするか」だけを指示して、実際のロジックは関数がやる。
じゃあ、まずテーブルを作成しよう:
-- studentsテーブルを作成
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
age INT NOT NULL,
last_modified TIMESTAMP
);
次に、last_modifiedフィールドを更新する関数を作成するよ:
-- last_modifiedを更新する関数
CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
-- last_modifiedフィールドに現在時刻をセット
NEW.last_modified := NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
この関数が何をしているか説明するね:
CREATE OR REPLACE FUNCTION update_last_modified()—update_last_modifiedという名前の関数を作成。すでに存在してたら上書きされる。RETURNS TRIGGER— この関数はトリガー用だよ、って指定。NEW.last_modified := NOW();—NOW()関数で現在の日付と時刻をlast_modifiedにセット。RETURN NEW;— 更新したレコードを返す。AFTERトリガーではこれが必須。
トリガーを作成する
関数を作ったら、今度はトリガー自体を作ってstudentsテーブルに紐付けるよ。やり方はこんな感じ:
-- レコード挿入後のトリガーを作成
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();
ここでやってること:
CREATE TRIGGER set_last_modified—set_last_modifiedという名前のトリガーを作成。AFTER INSERT— テーブルに行が挿入された後にトリガーが動く。ON students—studentsテーブルに紐付け。FOR EACH ROW— 新しい行ごとにトリガーが実行される。EXECUTE FUNCTION update_last_modified();— さっき作った関数を呼び出す。
注意:トリガー名(set_last_modified)や関数名(update_last_modified)は好きに決めてOKだけど、分かりやすい名前にしておくとコードが読みやすいよ。
トリガーのテスト
トリガーがちゃんと動くか確認しよう。まずはstudentsテーブルにいくつかレコードを追加する:
-- テーブルにデータを挿入
INSERT INTO students (name, age) VALUES ('イワン イワノフ', 20);
INSERT INTO students (name, age) VALUES ('アンナ ペトロワ', 22);
次に、テーブルの中身を見てみよう:
-- テーブルのデータを表示
SELECT * FROM students;
期待される結果はこんな感じ:
| id | name | age | last_modified |
|---|---|---|---|
| 1 | オット ミン | 20 | 2023-10-10 14:30:45 |
| 2 | アンナ ソン | 22 | 2023-10-10 14:31:12 |
last_modifiedフィールドが、それぞれのレコードで自動的に現在の日付と時刻で埋まってるのが分かるね。
発生しがちなエラー
- エラー: "relation does not exist"(リレーションが存在しません)トリガー作成時。このエラーは
studentsテーブルがまだ作成されてないときに出る。トリガーを作る前にテーブルを作成したか確認しよう。 - 権限エラー。データベースユーザーに関数やトリガーを作成する権限がないと、トリガーは作れない。ユーザーの権限をチェックしよう。
- トリガーで関数呼び出し忘れ。
EXECUTE FUNCTION update_last_modified()を書くのを忘れると、トリガーは何もできないよ。
トリガーの改良: 条件追加
実際のプロジェクトでは、特定の条件でトリガーを動かしたいこともある。例えば、ageフィールドが18未満ならlast_modifiedを更新したくない場合。これはWHEN条件でできるよ:
-- 条件付きトリガーを作成
CREATE TRIGGER set_last_modified
AFTER INSERT ON students
FOR EACH ROW
WHEN (NEW.age >= 18)
EXECUTE FUNCTION update_last_modified();
これで、ageが18以上の学生だけlast_modifiedが更新されるようになる。
実際の使い道
こういうトリガーは、リアルなプロジェクトでもよく使われてる。例えば:
- レコードの最終更新日時を自動で更新(今回やったやつ)。
- データベースの変更を監視して、ログテーブルに記録する。
- データの整合性を保つために、操作前に関連テーブルをチェックする。
- 法的や企業ルールのためのデータ監査。
こういうスキルは、銀行システムや在庫管理、CRMみたいにデータの正確さや信頼性が大事なシステムで特に役立つよ。
GO TO FULL VERSION