程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> 觸發器四(學習筆記),觸發器學習筆記

觸發器四(學習筆記),觸發器學習筆記

編輯:Oracle教程

觸發器四(學習筆記),觸發器學習筆記


REFERENCING子句:

使用“:new.字段”或者是“:old.字段”標記不清,那麼也可以通過REFERENCING子句為這兩個標識符設置別名,例如可以將“:new”設置為:emp_new,或者將“:old”設置為:emp_old。
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;

使用WHEN子句定義觸發條件:

在WHEN子句中也可以用":new"和":old"訪問修改前後的數據,在WHEN子句中使用new和old時可以不加前面的":"號 示例一、增加員工中判斷員工工資是否存在,如果工資為0則報錯
--創建觸發器
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   No. 觸發器謂詞 描述 1 INSERTING 如果觸發語句為INSERT,返回TRUE,否則返回FALSE 2 UPDATING 如果觸發語句為UPDATE,返回TRUE,否則返回FALSE 3 DELETING 如果觸發語句為DELETE,返回TRUE,否則返回FALSE  

 

示例三、使用日志表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;

使用FOLLOWS子句

為一個表創建了多個觸發器,在觸發時,是不會按照用戶希望的順序執行觸發的,

在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

按指定順序觸發

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved