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

觸發器七(復合觸發器)(學習筆記),復合觸發器學習筆記

編輯:Oracle教程

觸發器七(復合觸發器)(學習筆記),復合觸發器學習筆記


復合觸發器

復合觸發器是在Oracle 11g之後引入進來的一種新結構的觸發器,復合觸發器既是表級觸發器又是行級觸發器。在之前針對於不同級別的觸發器,如果要在一張數據表上完成表級觸發(BEFORE和AFTER)與行級觸發(BEFORE和AFTER)則需要編寫四個觸發器才可以完成,而有了復合觸發器之後,只需要一個觸發器就可以定義完全部的四個功能 使用復合觸發器可以捕獲四個操作事件: 復合觸發器創建語法
--復合觸發器創建語法
CREATE [OR REPLACE] TRIGGER 觸發器名稱
    FOR [INSERT | UPDATE | UPDATE OF 列名稱 [,列名稱,...] | DELETE] ON 表名稱
    COMPOUND TRIGGER
        [ BEFORE STATEMENT IS    -- 語句執行前觸發(表級)
            [ 聲明部分 ; ]
        BEGIN
            程序主體部分 ;
        END BEFORE STATEMENT ; ]
        [ BEFORE EACH ROW IS    -- 語句執行前觸發(行級)
            [ 聲明部分 ; ]
        BEGIN
            程序主體部分 ;
        END BEFORE EACH ROW ; ]
        [ AFTER STATEMENT IS    -- 語句執行後觸發(表級)
            [ 聲明部分 ; ]
        BEGIN
            程序主體部分 ;
        END AFTER STATEMENT ; ]
        [ AFTER EACH ROW IS    -- 語句執行後觸發(行級)
            [ 聲明部分 ; ]
        BEGIN
            程序主體部分 ;
        END AFTER EACH ROW ; ]
    END ;
    /

 示例一、創建復合觸發器

--創建復合觸發器
create or replace trigger compound_trigger
  FOR INSERT OR UPDATE OR DELETE  on dept  
   compound TRIGGER

    BEFORE STATEMENT IS  -- 語句執行前觸發(表級)
    BEGIN
      DBMS_OUTPUT.put_line('1、BEFORE STATEMENT .') ;
    END BEFORE STATEMENT;
    BEFORE EACH ROW IS  -- 語句執行前觸發(行級)
    BEGIN
      DBMS_OUTPUT.put_line('2、BEFORE EACH ROW .') ;
    END BEFORE EACH ROW;
    AFTER STATEMENT IS  -- 語句執行後觸發(表級)
    BEGIN
      DBMS_OUTPUT.put_line('3、AFTER STATEMENT .') ;
    END AFTER STATEMENT;
    AFTER EACH ROW IS  -- 語句執行後觸發(行級)
    BEGIN
      DBMS_OUTPUT.put_line('4、AFTER EACH ROW .') ;
    END AFTER EACH ROW;

end compound_trigger;
--測試
INSERT INTO dept(deptno,Dname,loc)
VALUES(97,'RD','深圳');
SELECT * FROM dept;
--結果
1、BEFORE STATEMENT .
2、BEFORE EACH ROW .
4、AFTER EACH ROW .
3、AFTER STATEMENT .

示例二、

定義觸發器,此觸發器可以完成如下的功能 在周末時間不允許更新emp表數據; 在更新數據時,要求將所有增加的數據自動變為大寫; 在更新完成之後,新增雇員的工資不得高於公司的平均工資
--創建復合觸發器
create or replace trigger emp_compound_trigger
  FOR INSERT OR UPDATE OR DELETE on emp  
  compound TRIGGER
           BEFORE STATEMENT IS         --表級,語句執行前觸發                         
            v_curweek                     VARCHAR2(20);          --聲明,--周末不能更新                   
           BEGIN                           
             SELECT to_char(SYSDATE,'day') INTO v_curweek FROM dual;
             IF TRIM(v_curweek) IN ('星期六','星期日') THEN
               raise_application_error(-20004,'周末不允許更新員工表emp');
               END IF;
                 EXCEPTION
            WHEN OTHERS THEN
              dbms_output.put_line(SQLCODE||SQLERRM);
           END BEFORE STATEMENT;
           BEFORE EACH ROW IS                             --行級,語句執行前觸發                       
                v_avgsal           emp.sal%TYPE;           --聲明平均工資變量              
           BEGIN
             IF inserting OR updating THEN
               :new.ename:=upper(:new.ename);
               :new.job:=upper(:new.job);
             END IF;
             IF inserting THEN
                 SELECT AVG(sal) INTO v_avgsal FROM emp;
                 IF :new.sal > v_avgsal THEN
                   raise_application_error(-20005,'新員工工資不重高於公司平均工資!');
                 END IF;
             END IF;
               EXCEPTION
            WHEN OTHERS THEN
              dbms_output.put_line(SQLCODE||SQLERRM);
          END BEFORE EACH ROW;
        
           
end emp_compound_trigger;
--測試
INSERT INTO emp(empno,ename,job,mgr,hiredate,sal,deptno)
VALUES(8888,'test','clerk',7369,SYSDATE,1000,10);

--時間改為周末
INSERT INTO emp(empno,ename,job,mgr,hiredate,sal,deptno)
VALUES(9999,'test1','clerk',7369,SYSDATE,5000,20);

 

 

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