Trigger 介紹

Trigger 介紹

相關應用

1.

    after insert or update of column1, column2, column3 on table名稱
    for each row
begin

    IF inserting THEN --insert即執行, 除了inserting外, 還可用updating
        …
    END IF;
end;

2.

    before update on tableName
    for each row
declare
    start_dt timestamp;
    end_dt timestamp;
begin
    start_dt := :old.column1; --將update前的row column1值放入start_dt
    end_dt := :new.column1; --將update前的row column1值放入end_dt
    :new.column2 := start_dt; --update column2欄位
    :new.column3 := end_dt; --update column3欄位
end test;

轉貼 : http://oracled2k.pixnet.net/blog/post/19131028

Oracle觸發器開發與設計 
一、 什麼是觸發器?
數據庫觸發器是一個存儲的PL/SQL程序塊,它與一個基表聯系,當在表上執行特定的數據庫維護(插入、刪除、更新這三種操作)時,隱含地執行一個PL/SQL程序塊。
二、觸發器的作用:
。防止非法的數據庫操縱、維護數據庫安全
。對數據庫的操作進行審計,存儲歷史數據
。完成數據庫初始化處理
。控制數據庫的數據完整性
。進行相關數據的修改
。完成數據復制
。自動完成數據庫統計計算
。限制數據庫操作的時間、權限等,控制實體的安全性
三、觸發器的組成:
1、觸發時間:觸發器事件的時間次序(before, afer)[2]
2、觸發事件:什麼SQL語句會引起觸發器觸發(Insert, delete, update)[3]
3、觸發子體:觸發器觸發時要執行的操作(一個完整的PL/SQL程序)
4、觸發類型:觸發器被執行的次數(語句級、行級)[2] //語句級只執行一次,行級會執行多次。
[*]一個表上最多可以創建12個不同類型的觸發器:3*2*2 = 12
四、創建觸發器注意事項:
1、在觸發器中可以調用存儲過程、包;在存儲過程中不得調用觸發器。
2、在觸發器中不得使用commit, rollback, savepoint語句。
3、在觸發器中不得間接調用含有commit, rollback, savepoint的語句的存儲過程及函數。
五、創建語句級觸發器:
語句級觸發器: 請參考PowerPoint教程:存儲過程1.ppt[Page19] 該觸發器在數據庫操作時只執行一次。
說明:
。update中的of是可選項,用于指定語句要修改的列
。要創建的觸發器已經存在時,使用replace選項
//例1:before型觸發器: 

  before delete on emp
  Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18)
   then dbms_output.put_line('現在是非工作時間,請退出!!!');
   end if;
  End;

[觸發器數據字典]
SQL> select table_owner, table_name,trigger_body from user_triggers where trigger_name='DELEMP';
//例2:After型觸發器:

    after insert on emp  // 如果是before,就會比after的結果少一名。
Declare
    v_empcount number(7);
Begin
    select count(*) into v_empcount from emp;
    dbms_output.put_line('目前員工總數已達到:'|| v_empcount|| '名。');
End;

//例3:多個觸發條件

    before delete or insert or update on emp
Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between 8 and 18)
   then dbms_output.put_line('現在是非工作時間,請不要修改數據!!!');
   end if;
End;

// 更完善的寫法:

  before delete or insert or update  on emp
  Begin
   if (DELETING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('現在是非工作時間,不要刪除數據!');
   elsif (UPDATING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8 and 18))
   then dbms_output.put_line('現在是非工作時間,不要更新數據!');
   elsif (INSERTING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('現在是非工作時間,不要插入數據!');
   end if;
  End;

六、創建行級觸發器:
等級觸發器:增加選項for each row, 使觸發器在每一行上觸發。
1、創建行級觸發器注意事項:
(1) 在行級觸發器中,在列名前增加old表示該列修改前值,增加new表示該列修改後值。
(2) 在PL/SQL中引用時,前邊增加冒號。
[例4: 行級觸發器] //必須是對所有的行進行操作才行。

    Before update on emp 
    for each row 
Begin
    dbms_output.put_line(:old.sal||'--------->'||:new.sal);
End;

[例5:保存歷史數據,這種使用方法很重要,用來保存關鍵表的歷史數據]

    Before update or delete on emp
    for each row
Begin
    Insert into oldemp(empno, ename,job,hiredate,sal)
        values(:old.empno,:old.ename,:old.job,sysdate,:old.sal);
End;

SQL> create table oldemp as select empno, ename,job,hiredate,sal from emp where 1>2;
[例6:修改外鍵]

    after update on dept
    for each row
Begin
update emp
    set emp.deptno = :new.deptno
    where emp.deptno = :old.deptno;
End;

[例7:刪除外鍵、刪除相關數據]

    before delete on dept
    for each row
Begin
    delete from emp where deptno = :old.empno;
End;

七、觸發器管理
1、使觸發器失效:
SQL> alter trigger 觸發器名稱 disable;  // 失效
SQL> Alter Trigger 觸發器名稱 enable;  // 生效
SQL> Alter table 表名 DISABLE all triggers; // 一個表上的所有觸發器失效
SQL> Alter table 表名 ENABLE all triggers; // 使一個表上的所有觸發器生效
SQL> Drop Trigger 觸發器名;  // 刪除觸發器;