變異表是指激發觸發器的DML語句所操作的表
當對一個表創建行級觸發器時,有下列兩條限制:
KEY,UNIQUE 或FOREIGN KEY關鍵字的列, 但
可以修改其他列
例如:有這樣一個需求:在更新員工所在部門或向部門插入新員工時,部門中員工人數不超過7人
如果按照下面的觸發器寫就會使UPDATE操作時報錯
CREATE OR REPLACE TRIGGER updatetrigger
BEFORE UPDATE ON EMP
FOR EACH ROW
DECLARE
v_num NUMBER;
BEGIN
SELECT count(*) INTO v_num FROM emp
WHERE deptno = :new.deptno;
IF (v_num > 7) THEN
RAISE_APPLICATION_ERROR(-20001,
'員工數多於'||v_num);
END IF;
END updatetrigger;
ORA-04091: 表 SCOTT.EMP 發生了變化, 觸發器/函數不能讀它
ORA-06512: 在 "SCOTT.UPDATETRIGGER", line 4
ORA-04088: 觸發器 'SCOTT.UPDATETRIGGER' 執行過程中出錯
如果既想更新變異表,同時又需要查詢變異表,那麼如何處理呢?
將行級觸發器與語句級觸發器結合起來,在行級觸發器中獲取要修改的記錄的信息,存放到一個軟件包的全局變量中,然後在語句級後觸發器中利用軟件包中全局變量信息對變異表的查詢,並根據查詢的結果進行業務處理
例如:
爲了實現在更新員工所在部門或向部門插入新員工時,部門中員工人數不超過7人,可以在emp表上創建兩個觸發器,同時創建一個共享信息的包
CREATE OR REPLACE PACKAGE mutate_pkg
AS
v_deptno NUMBER(2);
END;
CREATE OR REPLACE TRIGGER rmutate_trigger
BEFORE INSERT OR UPDATE OF deptno ON EMP
FOR EACH ROW
BEGIN
mutate_pkg.v_deptno:=:new.deptno;
END;
CREATE OR REPLACE TRIGGER smutate_trigger
AFTER INSERT OR UPDATE OF deptno ON EMP
DECLARE
v_num number(3);
BEGIN
SELECT count(*) INTO v_num FROM emp
WHERE deptno = mutate_pkg.v_deptno;
IF v_num>7 THEN
RAISE_APPLICATION_ERROR(-20003,'這部門的員工太多了 '||
mutate_pkg.v_deptno);
END IF;
END;
這樣操作,就不會報ORA-04091: 表SCOTT.EMP 發生了變化,觸發器/函數不能讀它錯誤了