2014-06-14 Created By BaoXinjian
一、基本概念
觸發器是許多關系數據庫系統都提供的一項技術。在ORACLE系統里,觸發器類似過程和函數,都有聲明,執行和異常處理過程的PL/SQL塊。
觸發器在數據庫里以獨立的對象存儲,它與存儲過程和函數不同的是,存儲過程與函數需要用戶顯示調用才執行,而觸發器是由一個事件來啟動運行。即觸發器是當某個事件發生時自動地隱式運行。並且,觸發器不能接收參數。所以運行觸發器就叫觸發或點火(firing)。ORACLE事件指的是對數據庫的表進行的INSERT、UPDATE及DELETE操作或對視圖進行類似的操作。ORACLE將觸發器的功能擴展到了觸發ORACLE,如數據庫的啟動與關閉等。所以觸發器常用來完成由數據庫的完整性約束難以完成的復雜業務規則的約束,或用來監視對數據庫的各種操作,實現審計的功能。
1. 觸發器事件:insert, update, insert
2. 觸發時間: after, before
3. 觸發參數: :old和:new
(1). delete 只有:old
(2). insert 只有:new
(3). update 同時存在:old 和:new
4 觸發層級:行級觸發器,語句級觸發器
(1). 行級觸發器是加入了for each row
(2). 語句級觸發器不需要for each row
只有應該了for each row才會有:old 或者:new
5. 其他
(1). 觸發器是不能使用rollback
(2). 觸發器拋出異常:raise_application_error('-2000','不能刪除'); -20999到-20000
6. 觸發器的主要作用
- 1、 允許/限制對表的修改
- 2、 自動生成派生列,比如自增字段
- 3、 強制數據一致性
- 4、 提供審計和日志記錄
- 5、 防止無效的事務處理
- 6、 啟用復雜的業務邏輯
7. 觸發器的組成部分:
- 觸發器名稱
- 觸發語句
- 觸發器限制
- 觸發操作
8. 觸發器的類型
- 語句觸發器
- 行觸發器
- INSTEAD OF 觸發器
- 系統條件觸發器
- 用戶事件觸發器
二、觸發器的結構
觸發器的組成部分:
- 觸發器名稱
- 觸發語句
- 觸發器限制
- 觸發操作
1. 觸發器名稱
create trigger biufer_employees_department_id
命名習慣:
biufer(before insert update for each row)
employees 表名
department_id 列名
2. 觸發語句
表或視圖上的DML語句 或DDL語句
數據庫關閉或啟動,startup shutdown 等等
before insert or update
of department_id
on employees
referencing old as old_value
new as new_value
for each row
說明:
(1) 無論是否規定了department_id ,對employees表進行insert的時候
(2) 對employees表的department_id列進行update的時候
3. 觸發器限制
when (new_value.department_id<>80 )
限制不是必須的。此例表示如果列department_id不等於80的時候,觸發器就會執行。
其中的new_value是代表更新之后的值。
4. 觸發操作
是觸發器的主體
begin
:new_value.commission_pct :=0;
end;
主體很簡單,就是將更新后的commission_pct列置為0
觸發器不會通知用戶,便改變了用戶的輸入值。
三、具體案例 - 使用最多的行級出發器
案例:當表進行增刪改后輸出信息,以監控表的增刪
1. 行級觸發器
1 CREATE OR REPLACE TRIGGER test_trigger 2 AFTER INSERT OR DELETE OR UPDATE
3 ON xxgl_test_je_headers 4 FOR EACH ROW 5 BEGIN
6 IF INSERTING 7 THEN
8 DBMS_OUTPUT.put_line ('I'); 9 DBMS_OUTPUT.put_line ('insert batch_id='||:new.je_batch_id); 10 ELSIF UPDATING 11 THEN
12 DBMS_OUTPUT.put_line ('U'); 13 DBMS_OUTPUT.put_line ('update old batch_name='||:old.batch_name); 14 DBMS_OUTPUT.put_line ('update new batch_name='||:new.batch_name); 15 ELSIF DELETING 16 THEN
17 DBMS_OUTPUT.put_line ('D'); 18 DBMS_OUTPUT.put_line ('delete batch_id='||:old.je_batch_id); 19 END IF; 20 END;
2. Create 測試該觸發器
3. Update 測試該觸發器
4. Delete 測試該觸發器
Thanks and Regards