1. 程式人生 > >oracle數據庫之觸發器

oracle數據庫之觸發器

let mpi drop 影響 重新 刪除日誌 weight 更新 情況下

觸發器是許多關系數據庫系統都提供的一項技術。在 ORACLE 系統裏,觸發器類似過程和函數,都有聲明,執行和異常處理過程的 PL/SQL

一、 觸發器類型 觸發器在數據庫裏以獨立的對象存儲,它與存儲過程不同的是,存儲過程通過其它程序來啟動運行或直接啟動運行,而觸發器是由一個事件來啟動運行即觸發器是當某個事件發生時自動地隱式運行。並且,觸發器不能接收參數。所以運行觸發器就叫觸發或點火(firingORACLE 事件指的是對數據庫的表進行的INSERTUPDATE DELETE 操作或對視圖進行類似的操作。ORACLE 將觸發器的功能擴展到了觸發 ORACLE,如數據庫的啟動與關閉等。

(一) DML 觸發器

ORACLE 可以在 DML 語句進行觸發,可以在 DML 操作前或操作後進行觸發,並且可以對每個行或語句操作上進行觸發

(二) 替代觸發器

由於在 ORACLE 裏,不能直接對由兩個以上的表建立的視圖進行操作。所以給出了替代觸發器。

(三)系統觸發器

它可以在 ORACLE 數據庫系統的事件中進行觸發,如 ORACLE 系統的啟動與關閉等。

二、觸發器組成:

觸發事件:即在何種情況下觸發 TRIGGER; 例如:INSERT, UPDATE, DELETE。

觸發時間:即該 TRIGGER 是在觸發事件發生之前(BEFORE)還是之後(AFTER)觸發,也就是觸發事件和該 TRIGGER 的操作順序。

觸發器本身:即該 TRIGGER 被觸發之後的目的和意圖,正是觸發器本身要做的事情。例如:PL/SQL 塊。

觸發頻率:說明觸發器內定義的動作被執行的次數。即語句級(STATEMENT)觸發器和行級(ROW)觸發器。語句級(STATEMENT)觸發器:是指當某觸發事件發生時,該觸發器只執行一次;行級(ROW)觸發器是指當某觸發事件發生時,對受到該操作影響的每一行數據,觸發器都單獨執行一次。

三、 創建觸發器

創建觸發器的一般語法是:

CREATE [OR REPLACE] TRIGGER trigger_name

{BEFORE | AFTER }

{INSERT | DELETE |
UPDATE [OF column [, column …]]} ON [schema.] table_name [FOR EACH ROW ] [WHEN condition] trigger_body;

其中:

BEFORE 和 AFTER 指出觸發器的觸發時序分別為前觸發和後觸發方式,前觸發是在執行觸發事件之前觸發當前所創建的觸發器,後觸發是在執行觸發事件之後觸發當前所創建的觸發器;

FOR EACH ROW 選項說明觸發器為行觸發器。行觸發器和語句觸發器的區別表現在:行觸發器要求當一個 DML 語句操做影響數據庫中的多行數據時,對於其中的每個數據行,只要它們符合觸發約束條件,均激活一次觸發器;而語句觸發器將整個語句操作作為觸發事件,當它符合約束條件時,激活一次觸發器。當省略 FOR EACH ROW 選項時BEFORE AFTER 觸發器為語句觸發器,而 INSTEAD OF 觸發器則為行觸發器。

WHEN 子句說明觸發約束條件。Condition 為一個邏輯表達時,其中必須包含相關名稱,而不能包含查詢語句,也不能調用 PL/SQL 函數。WHEN 子句指定的觸發約束條件只能用在 BEFORE 和 AFTER 行觸發器中,不能用在 INSTEAD OF 行觸發器和其它類型的觸發器中。

當一個基表被修改( INSERT, UPDATE, DELETE)時要執行的存儲過程,執行時根據其所依附的基表改動而自動觸發,因此與應用程序無關,用數據庫觸發器可以保證數據的一致性和完整性。每張表最多可建立 12 種類型的觸發器,它們是:

BEFORE INSERT

BEFORE INSERT FOR EACH ROW

AFTER INSERT

AFTER INSERT FOR EACH ROW

BEFORE UPDATE

BEFORE UPDATE FOR EACH ROW

AFTER UPDATE

AFTER UPDATE FOR EACH ROW

BEFORE DELETE

BEFORE DELETE FOR EACH ROW

AFTER DELETE

AFTER DELETE FOR EACH ROW

(一) 觸發器觸發次序

1、執行 BEFORE 語句級觸發器

對與受語句影響的每一行

2、執行 BEFORE 行級觸發器

3、執行 DML 語句

3、執行 AFTER 行級觸發器

4、執行 AFTER 語句級觸發器

(二) 創建 DML 觸發器

觸發器名可以和表或過程有相同的名字,但在一個模式中觸發器名不能相同。

觸發器的限制

l CREATE TRIGGER 語句文本的字符長度不能超過 32KB;

l 觸發器體內的 SELECT 語句只能為 SELECT … INTO …結構,或者為定義遊標所使用的 SELECT 語句

l 觸發器中不能使用數據庫事務控制語句 COMMIT; ROLLBACK, SVAEPOINT 語句;

l 由觸發器所調用的過程或函數也不能使用數據庫事務控制語句;

問題:當觸發器被觸發時,要使用被插入、更新或刪除的記錄中的列值,有時要使用操作前、 後

技術分享

1: 建立一個觸發器, 當職工表 emp 表被刪除一條記錄時,把被刪除記錄寫到職工表刪除日誌表中去。

技術分享

(三) 創建替代(INSTEAD OF)觸發器

創建觸發器的一般語法是:

CREATE [OR REPLACE] TRIGGER trigger_name

INSTEAD OF

{INSERT | DELETE | UPDATE [OF column [, column …]]}

ON [schema.] view_name

[FOR EACH ROW ]

[WHEN condition]

trigger_body;

其中:

BEFORE 和 AFTER 指出觸發器的觸發時序分別為前觸發和後觸發方式,前觸發是在執行觸發事件之前觸發當前所創建的觸發器,後觸發是在執行觸發事件之後觸發當前所創建的觸發器。INSTEAD OF 選項使 ORACLE 激活觸發器,而不執行觸發事件只能對視圖和對象視圖建立 INSTEAD OF觸發器,而不能對表、模式和數據庫建立 INSTEAD OF 觸發器。

FOR EACH ROW 選項說明觸發器為行觸發器。行觸發器和語句觸發器的區別表現在:行觸發器要求當一個 DML 語句操做影響數據庫中的多行數據時,對於其中的每個數據行,只要它們符合觸發約束條件,均激活一次觸發器;而語句觸發器將整個語句操作作為觸發事件,當它符合約束條件時,激活一次觸發器。當省略 FOR EACH ROW 選項時,BEFORE 和 AFTER 觸發器為語句觸發器,而 INSTEAD OF 觸發器則為行觸發器。

WHEN 子句說明觸發約束條件。Condition 為一個邏輯表達時,其中必須包含相關名稱,而不能包含查詢語句,也不能調用 PL/SQL 函數。WHEN 子句指定的觸發約束條件只能用在 BEFORE 和 AFTER 行觸發器中,不能用在 INSTEAD OF 行觸發器和其它類型的觸發器中。

INSTEAD_OF 用於對視圖的 DML 觸發,由於視圖有可能是由多個表進行聯結(join)而成,因而並非是所有的聯結都是可更新的。但可以按照所需的方式執行更新,例如下面情況:

CREATE OR REPLACE VIEW emp_view AS

SELECT deptno, count(*) total_employeer, sum(sal) total_salary

FROM emp GROUP BY deptno;

在此視圖中直接刪除是非法:

SQL>DELETE FROM emp_view WHERE deptno=10;

DELETE FROM emp_view WHERE deptno=10

ERROR 位於第 1 行:

ORA-01732: 此視圖的數據操縱操作非法

但是可以創建 INSTEAD_OF 觸發器來為 DELETE 操作執行所需的處理,即刪除 EMP 表中所有基準行:

CREATE OR REPLACE TRIGGER emp_view_delete

INSTEAD OF DELETE ON emp_view FOR EACH ROW

BEGIN

DELETE FROM emp WHERE deptno= :old.deptno;

END emp_view_delete;

DELETE FROM emp_view WHERE deptno=10;

DROP TRIGGER emp_view_delete;

DROP VIEW emp_view;

(四)創建系統事件觸發器

ORACLE 提供的系統事件觸發器可以在 DDL 或數據庫系統上被觸發。DDL 指的是數據定義語言,如CREATE 、ALTER 及 DROP 等。而數據庫系統事件包括數據庫服務器的啟動或關閉,用戶的登錄與退出、數據庫服務錯誤等。創建系統觸發器的語法如下:

創建觸發器的一般語法是:

CREATE OR REPLACE TRIGGER [sachema.] trigger_name

{BEFORE|AFTER}

{ddl_event_list | database_event_list}

ON { DATABASE | [schema.] SCHEMA }

[WHEN_clause]

trigger_body;

其中: ddl_event_list:一個或多個 DDL 事件,事件間用 OR 分開;

database_event_list:一個或多個數據庫事件,事件間用 OR 分開;

系統事件觸發器既可以建立在一個模式上,又可以建立在整個數據庫上。當建立在模式(SCHEMA)之上時,只有模式所指定用戶的 DDL 操作和它們所導致的錯誤才激活觸發器, 默認時為當前用戶模式。當建立在數據庫(DATABASE)之上時,該數據庫所有用戶的 DDL 操作和他們所導致的錯誤,以及數據庫的啟動和關閉均可激活觸發器。要在數據庫之上建立觸發器時,要求用戶具有 ADMINISTER DATABASE TRIGGER 權限。

下面給出系統觸發器的種類和事件出現的時機(前或後):

技術分享

(五) 使用觸發器謂詞

ORACLE 提供三個參數 INSERTING, UPDATING, DELETING 用於判斷觸發了哪些操作。

技術分享

(六) 重新編譯觸發器

如果在觸發器內調用其它函數或過程,當這些函數或過程被刪除或修改後,觸發器的狀態將被標識為無效。當 DML 語句激活一個無效觸發器時,ORACLE 將重新編譯觸發器代碼,如果編譯時發現錯誤,這將導致 DML 語句執行失敗。

在 PL/SQL 程序中可以調用 ALTER TRIGGER 語句重新編譯已經創建的觸發器,格式為:

ALTER TRIGGER [schema.] trigger_name COMPILE [ DEBUG]

其中:DEBUG 選項要器編譯器生成 PL/SQL 程序條使其所使用的調試代碼。

三、 刪除和使能觸發器

(一)刪除觸發器

DROP TRIGGER trigger_name;

當刪除其他用戶模式中的觸發器名稱,需要具有 DROP ANY TRIGGER 系統權限,當刪除建立在數據庫上的觸發器時,用戶需要具有 ADMINISTER DATABASE TRIGGER 系統權限。

此外,當刪除表或視圖時,建立在這些對象上的觸發器也隨之刪除

1、 觸發器的狀態

有效狀態(ENABLE):當觸發事件發生時,處於有效狀態的數據庫觸發器 TRIGGER 將被觸發。

無效狀態(DISABLE):當觸發事件發生時,處於無效狀態的數據庫觸發器 TRIGGER 將不會被觸發,此時

就跟沒有這個數據庫觸發器(TRIGGER) 一樣。

數據庫 TRIGGER 的這兩種狀態可以互相轉換。格式為:

ALTER TIGGER trigger_name [DISABLE | ENABLE ];

例:

ALTER TRIGGER emp_view_delete DISABLE;

ALTER TRIGGER 語句一次只能改變一個觸發器的狀態,而 ALTER TABLE 語句則一次能夠改變與指定表相關的所有觸發器的使用狀態。格式為:

ALTER TABLE [schema.]table_name {ENABLE|DISABLE} ALL TRIGGERS;

例:使表 EMP 上的所有 TRIGGER 失效:

ALTER TABLE emp DISABLE ALL TRIGGERS;

oracle數據庫之觸發器