create or replace trigger myempaddsal_trigger before update on myemp REFERENCING OLD AS myemp_old NEW AS myemp_new for each row declare begin IF ABS((:myemp_new.sal - :myemp_old.SAL) / :myemp_old.SAL) > 0.1 THEN raise_application_error(-20005,'工資最大漲幅不能超過10%'); END IF; end myempaddsal_trigger;
--創建觸發器 create or replace trigger myemptestadd1 before insert on myemp for each ROW WHEN(new.Sal=0) declare begin raise_application_error(-20003,:NEW.EMPNO||'的工資為0,不合規定!'); end myemptestadd1; --執行添加 DECLARE BEGIN INSERT INTO myemp(empno,ename,job,mgr,sal,deptno)VALUES(9999,'Bdqn','MNAGER',7788,0,10); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; --結果 ORA-20003: 9999的工資為0,不合規定! ORA-06512: 在 "TESTS.MYEMPTESTADD1", line 4 ORA-04088: 觸發器 'TESTS.MYEMPTESTADD1' 執行過程中出錯
示例二、要求工資只能漲不能降
--創建觸發器 create or replace trigger myemptestadd1 before UPDATE on myemp for each ROW WHEN(new.Sal<old.Sal) declare begin raise_application_error(-20003,:old.EMPNO||'的工資只能漲不能降!'); end myemptestadd1; --執行錯誤的更新 DECLARE BEGIN UPDATE myemp SET sal=2000 WHERE empno=7788; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; --結果 ORA-20003: 7788的工資只能漲不能降! ORA-06512: 在 "TESTS.MYEMPTESTADD1", line 4 ORA-04088: 觸發器 'TESTS.MYEMPTESTADD1' 執行過程中出錯
在觸發器定義中專門提供了三個觸發器謂詞:INSERTING、UPDATING、DELETING
示例三、使用日志表deptlog表記錄相關操作dept表
-創建deptlog表 CREATE TABLE deptlog( logid NUMBER, TYPE VARCHAR2(20) NOT NULL, deptno NUMBER(2), logdate DATE, dname Varchar2(14) NOT NULL, loc Varchar2(13) NOT NULL, CONSTRAINT pk_logid PRIMARY KEY(logid) ); --創建序列 CREATE SEQUENCE deptlog_seq; --創建觸發器 create or replace trigger dept_trigger before INSERT OR UPDATE OR DELETE on dept for each row declare BEGIN IF inserting THEN INSERT INTO deptlog(logid,type,deptno,logdate,dname,loc) VALUES(deptlog_seq.nextval,'insert',:new.Deptno,SYSDATE,:NEW.DNAME,:new.Loc); ELSIF updating THEN INSERT INTO deptlog(logid,type,deptno,logdate,dname,loc) VALUES(deptlog_seq.nextval,'update',:new.Deptno,SYSDATE,:NEW.DNAME,:new.Loc); ELSIF deleting THEN INSERT INTO deptlog(logid,type,deptno,logdate,dname,loc) VALUES(deptlog_seq.nextval,'delete',:old.Deptno,SYSDATE,:old.DNAME,:old.Loc); END IF; end dept_trigger; --測試數據 INSERT INTO dept(deptno,dname,loc)VALUES(87,'測試','SZ'); INSERT INTO dept(deptno,dname,loc)VALUES(43,'公關','SZ'); UPDATE dept SET dname='拓展部' WHERE deptno=66; DELETE FROM dept WHERE deptno=87; commit; --查詢 SELECT * FROM dept; --查詢表 SELECT * FROM deptlog;
為一個表創建了多個觸發器,在觸發時,是不會按照用戶希望的順序執行觸發的,
在FOR EACH ROW後增加FOLLOWS 觸發器1名稱,表示在 觸發器1後觸發
--創建3個相同的觸發器 --觸發器1 create or replace trigger dept1 before INSERT OR UPDATE OR DELETE on dept for each row declare begin dbms_output.put_line('執行第1個觸發器 dept1'); end dept1; --觸發器2 create or replace trigger dept2 before INSERT OR UPDATE OR DELETE on dept for each ROW follows dept1 declare begin dbms_output.put_line('執行第2個觸發器 dept2'); end dept1; --觸發器3 create or replace trigger dept3 before INSERT OR UPDATE OR DELETE on dept for each ROW follows dept2 declare begin dbms_output.put_line('執行第3個觸發器 dept3'); end dept1;
執行更新,刪除,添加操作
INSERT INTO dept(deptno,dname,loc)VALUES(87,'測試','SZ'); INSERT INTO dept(deptno,dname,loc)VALUES(43,'公關','SZ'); UPDATE dept SET dname='拓展部' WHERE deptno=66; DELETE FROM dept WHERE deptno=87;
結果:
執行第1個觸發器 dept1 執行第2個觸發器 dept2 執行第3個觸發器 dept3
按指定順序觸發