PL/SQL – Triggers
この章では、PL/SQLのTriggersについて説明します。 トリガーとはストアドプログラムのことで、あるイベントが発生すると自動的に実行されたり、起動されたりします。
-
データベース操作(DML)ステートメント(DELETE、INSERT、UPDATE)
-
データベース定義(DDL)ステートメント(CREATE、ALTER、DROP)
-
データベース操作(DML)ステートメント(DELETE、INSERT、UPDATE)。
-
データベース操作 (SERVERERROR、LOGON、LOGOFF、STARTUP、SHUTDOWN)。
トリガーは、イベントが関連付けられているテーブル、ビュー、スキーマ、またはデータベース上で定義できます。
トリガーの利点
トリガーは次のような目的で書くことができます –
- いくつかの派生カラムの値を自動的に生成する
- 参照整合性の強化
- イベントのロギングやテーブル アクセスの情報を保存する
- 監査
- イベントのロギングやテーブル アクセスの情報を保存する
- 監査
- テーブルの同期レプリケーション
- セキュリティ権限の付与
- 無効なトランザクションの防止
。
トリガーの作成
トリガーを作成するための構文は –
CREATE TRIGGER trigger_name {BEFORE | AFTER | INSTEAD OF } {INSERT | UPDATE | DELETE} ON table_name WHEN (condition) DECLARE Declaration-statements BEGIN Executable-statements EXCEPTION Exception-handling-statements END;
どこでもよい。
-
CREATE TRIGGER trigger_name – trigger_nameを持つ既存のトリガーを作成または置換します。
-
{BEFORE|AFTER|INSTEAD OF}。 – これは、トリガーがいつ実行されるかを指定します。 INSTEAD OF 句は、ビュー上にトリガーを作成する際に使用されます。
-
{INSERT | UPDATE | DELETE} これは、DML操作を指定します。 –
-
– 更新される列名を指定します。
-
– トリガーに関連するテーブルの名前を指定します。
-
– INSERT、UPDATE、DELETE などの様々な DML 文の新旧の値を参照することができます。
-
– これは、行レベルのトリガーを指定します。 つまり、影響を受ける各行に対してトリガーが実行されます。
-
WHEN (condition) – これは、トリガーが発火する行の条件を提供します。 この句は、行レベルのトリガーでのみ有効です。
例
まず、前の章で作成して使用したCUSTOMERSテーブルを使用します –
Select * from customers; +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | | 4 | Chaitali | 25 | Mumbai | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 6 | Komal | 22 | MP | 4500.00 | +----+----------+-----+-----------+----------+
以下のプログラムは、CUSTOMERSテーブルに対して実行されるINSERTまたはUPDATEまたはDELETE操作に対して発火する、customersテーブルの行レベルのトリガーを作成します。 このトリガーは、古い値と新しい値の間の給与の差を表示します –
CREATE OR REPLACE TRIGGER display_salary_changes BEFORE DELETE OR INSERT OR UPDATE ON customers FOR EACH ROW WHEN (NEW.ID > 0) DECLARE sal_diff number; BEGIN sal_diff := :NEW.salary - :OLD.salary; dbms_output.put_line('Old salary: ' || :OLD.salary); dbms_output.put_line('New salary: ' || :NEW.salary); dbms_output.put_line('Salary difference: ' || sal_diff); END; /
上記のコードがSQLプロンプトで実行されると、以下の結果が得られます。
Trigger created.
ここで以下の点を考慮する必要があります –
-
OLD および NEW の参照は、テーブルレベルのトリガーでは使用できず、レコードレベルのトリガーで使用できます。
-
同じトリガーでテーブルを照会したい場合は、AFTER キーワードを使用する必要があります。なぜなら、トリガーは、最初の変更が適用され、テーブルが一貫した状態に戻った後でのみ、テーブルを照会したり、再び変更したりできるからです。
-
上記のトリガーは、テーブル上のDELETE、INSERT、UPDATE操作の前に発火するように書かれていますが、単一または複数の操作に対してトリガーを書くことができます。例えば、テーブル上のDELETE操作を使用してレコードが削除されるたびに発火するBEFORE DELETEのように書くことができます。
トリガーの発動
CUSTOMERSテーブルにいくつかのDML操作を行ってみましょう。 以下は、テーブルに新しいレコードを作成するINSERT文です –
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES (7, 'Kriti', 22, 'HP', 7500.00 );
CUSTOMERSテーブルにレコードが作成されると、上記のcreateトリガ, display_salary_changesが実行され、次のような結果が表示されます –
Old salary: New salary: 7500 Salary difference:
これは新しいレコードなので、古い給与は利用できず、上記の結果はnullとなります。 次に、CUSTOMERSテーブルに対してもう一つのDML操作を行ってみましょう。 UPDATE文はテーブルの既存のレコードを更新します –
UPDATE customers SET salary = salary + 500 WHERE id = 2;
CUSTOMERSテーブルでレコードが更新されると、上記のcreateトリガ, display_salary_changesが実行され、次のような結果が表示されます –
Old salary: 1500 New salary: 2000 Salary difference: 500