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
按指定順序觸發