一、什麼是觸發器 資料庫觸發器是一個與表相關聯的,存儲的PL/SQL 語句。每當一個特定的數據操作語句(insert update delete)在指定的表上發出時,Oracle自動執行觸發器中定義的語句序列。 觸發器的應用場景如下: 複雜的安全性檢查 數據的確認 資料庫審計 數據的備份和審計 二、 ...
一、什麼是觸發器
資料庫觸發器是一個與表相關聯的,存儲的PL/SQL 語句。每當一個特定的數據操作語句(insert update delete)在指定的表上發出時,Oracle自動執行觸發器中定義的語句序列。
觸發器的應用場景如下:
- 複雜的安全性檢查
- 數據的確認
- 資料庫審計
- 數據的備份和審計
二、創建Oracle觸發器的語法
CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE | AFTER } {INSERT | DELETE | UPDATE [OF column [, column …]]} [OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...] ON [schema.]table_name | [schema.]view_name [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}] [FOR EACH ROW ] [WHEN condition] PL/SQL_BLOCK | CALL procedure_name;
其中:
- BEFORE 和AFTER指出觸發器的觸發時序分別為前觸發和後觸發方式,前觸發是在執行觸發事件之前觸發當前所創建的觸發器,後觸發是在執行觸發事件之後觸發當前所創建的觸發器。
- FOR EACH ROW選項說明觸發器為行觸發器。
- 行觸發器和語句觸發器的區別表現在:行觸發器要求當一個DML語句操走影響資料庫中的多行數據時,對於其中的每個數據行,只要它們符合觸發約束條件,均激活一次觸發器;而語句觸發器將整個語句操作作為觸發事件,當它符合約束條件時,激活一次觸發器。
- 當省略FOR EACH ROW 選項時,BEFORE 和AFTER 觸發器為語句觸發器,而INSTEAD OF 觸發器則只能為行觸發器
- REFERENCING 子句說明相關名稱,在行觸發器的PL/SQL塊和WHEN 子句中可以使用相關名稱參照當前的新、舊列值,預設的相關名稱分別為OLD和NEW。觸發器的PL/SQL塊中應用相關名稱時,必須在它們之前加冒號(:),但在WHEN子句中則不能加冒號。
- WHEN 子句說明觸發約束條件。Condition 為一個邏輯表達時,其中必須包含相關名稱,而不能包含查詢語句,也不能調用PL/SQL 函數。WHEN 子句指定的觸發約束條件只能用在BEFORE 和AFTER 行觸發器中,不能用在INSTEAD OF 行觸發器和其它類型的觸發器中。
- 當一個基表被修改( INSERT, UPDATE, DELETE)時要執行的存儲過程,執行時根據其所依附的基表改動而自動觸發,因此與應用程式無關,用資料庫觸發器可以保證數據的一致性和完整性。
三、Oracle觸發器的類型
- 行級觸發器:對DML語句影響的每個行執行一次,例如,一條update語句更新了100條數據,如果我們針對update定義了行級觸發器,那麼行級觸發器將會被觸發100次 。
- 語句級觸發器:對每個DML語句執行一次,例如,一條update語句更新了200條數據,如果我們針對update定義了語句級觸發器,那麼語句級觸發器將會被觸發1次 。
四、利用資料庫觸發實現複雜的安全性檢查
/* 實施複雜的安全性檢查 禁止在非工作時間插入新員工 周末:to_char(sysdate,'day') in ('星期六','星期日') 上班前和下班後:to_number(to_char(sysdate,'hh24')) not between 9 and 18 */ create or replace trigger securityemp before insert on emp begin if to_char(sysdate,'day') in ('星期六','星期日') or to_number(to_char(sysdate,'hh24')) not between 9 and 18 then --禁止insert操作 拋出異常 raise_application_error(-20001,'禁止在非工作時間插入新員工'); end if; end; /
- 在上面的例子中,我們禁止在非工作時間插入新員工,從而實現執行insert語句時候的安全性檢查。