次の例は、行レベルの AFTER トリガーを示します。 新しい従業員行が挿入されると、トリガーは jobhist テーブルにその従業員に関する新しい行を追加します。 既存の従業員行が更新されると、トリガーは jobhist テーブル内でのその従業員に対する最新の行 (enddate 列が null であるもの) の enddate 列を現在の日付に設定し、従業員に対する新しい情報を記録した新しい行を jobhist テーブルに挿入します。
最後に、トリガーは、このアクションを説明する行を empchglog テーブルに追加します。
CREATE TABLE empchglog (
chg_date DATE,
chg_desc VARCHAR2(30)
);
CREATE OR REPLACE TRIGGER emp_chg_trig
AFTER INSERT OR UPDATE OR DELETE ON emp
FOR EACH ROW
DECLARE
v_empno emp.empno%TYPE;
v_deptno emp.deptno%TYPE;
v_dname dept.dname%TYPE;
v_action VARCHAR2(7);
v_chgdesc jobhist.chgdesc%TYPE;
BEGIN
IF INSERTING THEN
v_action := 'Added';
v_empno := :NEW.empno;
v_deptno := :NEW.deptno;
INSERT INTO jobhist VALUES (:NEW.empno, SYSDATE, NULL,
:NEW.job, :NEW.sal, :NEW.comm, :NEW.deptno, 'New Hire');
ELSIF UPDATING THEN
v_action := 'Updated';
v_empno := :NEW.empno;
v_deptno := :NEW.deptno;
v_chgdesc := '';
IF NVL(:OLD.ename、 '-null-')! = NVL(:NEW.ename, '-null-') THEN
v_chgdesc := v_chgdesc || 'name, ';
END IF;
IF NVL(:OLD.job, '-null-') ! = NVL(:NEW.job, '-null-') THEN
v_chgdesc := v_chgdesc || 'job, ';
END IF;
IF NVL(:OLD.sal, -1) ! = NVL(:NEW.sal, -1) THEN
v_chgdesc := v_chgdesc || 'salary, ';
END IF;
IF NVL(:OLD.comm, -1) ! = NVL(:NEW.comm, -1) THEN
v_chgdesc := v_chgdesc || 'commission, ';
END IF;
IF NVL(:OLD.deptno, -1) ! = NVL(:NEW.deptno, -1) THEN
v_chgdesc := v_chgdesc || 'department, ';
END IF;
v_chgdesc := 'Changed ' || RTRIM(v_chgdesc, ', ');
UPDATE jobhist SET enddate = SYSDATE WHERE empno = :OLD.empno
AND enddate IS NULL;
INSERT INTO jobhist VALUES (:NEW.empno, SYSDATE, NULL,
:NEW.job, :NEW.sal, :NEW.comm, :NEW.deptno, v_chgdesc);
ELSIF DELETING THEN
v_action := 'Deleted';
v_empno := :OLD.empno;
v_deptno := :OLD.deptno;
END IF;
INSERT INTO empchglog VALUES (SYSDATE,
v_action || ' employee # ' || v_empno);
END;
次の SQL 文シーケンスでは、最初に 2 つの個別の INSERT 文を使用して 2 人の従業員を追加しています。 次に、1 つの UPDATE 文を使用して、両方が更新されます。 jobhist テーブルの内容は、影響を受ける各行に対するトリガーのアクションを示します。すなわち、2 人の新従業員に対応する 2 つの新規雇用エントリと、2 人の従業員に対するコミッションの更新に対応する 2 つのコミッション変更レコードです。 empchglog テーブルは、トリガーが 2 つの行に対する各アクションに対して 1 回、合計 4 回発火することも示しています。
INSERT INTO emp VALUES (9003,'PETERS','ANALYST',7782,SYSDATE,5000.00,NULL,40);
INSERT INTO emp VALUES (9004,'AIKENS','ANALYST',7782,SYSDATE,4500.00,NULL,40);
UPDATE emp SET comm = sal * 1.1 WHERE empno IN (9003, 9004);
SELECT * FROM jobhist WHERE empno IN (9003, 9004);
EMPNO STARTDATE ENDDATE JOB SAL COMM DEPTNO CHGDESC
| ------------ | --------- | ------- | ------------------ ----------------------- |
9003 31-MAR-05 31-MAR-05 ANALYST 5000 40 New Hire
9004 31-MAR-05 31-MAR-05 ANALYST 4500 40 New Hire
9003 31-MAR-05 ANALYST 5000 5500 40 Changed commission
9004 31-MAR-05 ANALYST 4500 4950 40 Changed commission
SELECT * FROM empchglog;
CHG_DATE CHG_DESC
--------- ------------------------------
31-MAR-05 Added employee # 9003
31-MAR-05 Added employee # 9004
31-MAR-05 Updated employee # 9003
31-MAR-05 Updated employee # 9004
最後に、両方の従業員は、1 つの DELETE 文を使用して削除されます。 empchglog テーブルは、トリガーが削除された従業員ごとに 1 回ずつ、計 2 回発火したことを示しています。
DELETE FROM emp WHERE empno IN (9003, 9004);
SELECT * FROM empchglog;
CHG_DATE CHG_DESC
--------- ------------------------------
31-MAR-05 Added employee # 9003
31-MAR-05 Added employee # 9004
31-MAR-05 Updated employee # 9003
31-MAR-05 Updated employee # 9004
31-MAR-05 Deleted employee # 9003
31-MAR-05 Deleted employee # 9004