標籤:
1.DML觸發器
顧名思義,DML觸發器是由DML語句觸發的.例如資料庫的INSERT/UPDATE/DELETE操作都可以觸發該類型的觸發器. 它們可以在這些語句之前或之後觸發,或者在行級上觸發(就是說對於每個受影響的行都觸發一次)
例如我們有一張表TABLE1 ,總共有三個欄位 ID,姓名,年齡 ,當我們在插入時希望ID可以自動產生,那麼可以建立一個觸發器
CREATE OR REPLACE TRIGGER TR_INSERT_ID BEFORE INSERT ON TABLE1 BEGIN SELECT T.NEXTVAL INTO :NEW.ID FROM DUAL; END;
那麼當我們插入該表的時候,ID欄位會自動填滿.
2.替代觸發器
替代觸發器只能使用在視圖上,與DML不同的是,DML觸發器是運行在DML之外的,而替代觸發器是代替激發它的DML語句運行.替代觸發器是行級,舉個例子,這裡有個視圖:
--例子來源insteadOf.sql
CREATE OR REPLACE VIEW classes_rooms AS SELECT department, course, building, room_numbe FROM rooms, classes WHERE rooms.room_id = classes.room_id;
直接對視圖進行插入操作非法的.因為插入操作要求對兩個表都進行修改,例如
--例子來源insteadOf.sql
如果使用替代
INSERT INTO classes_rooms (department, course, building, room_number) 2 VALUES (‘MUS‘, 100, ‘Music Building‘, 200); INSERT INTO classes_rooms (department, course, building, room_number) * ERROR at line 1: ORA-01732: data manipulation operation not legal on this view
觸發器,那麼就可以解決這個問題:
CREATE TRIGGER ClassesRoomsInsert INSTEAD OF INSERT ON classes_rooms DECLARE v_roomID rooms.room_id%TYPE; BEGIN -- First determine the room ID SELECT room_id INTO v_roomID FROM rooms WHERE building = :new.building AND room_number = :new.room_number; -- And now update the class UPDATE CLASSES SET room_id = v_roomID WHERE department = :new.department AND course = :new.course; END ClassesRoomsInsert;
該觸發器就可以正常工作了
3.系統觸發器
這種觸發器是發生在如資料庫啟動或關閉等系統事件時,不是在執行DML語句時發生,當然也可以在DDL時觸發.
不管是以上三種的哪一種,建立的文法都是一致的.
CREATE [OR REPLACE] TRIGGER trigger_name ...{BEFORE | AFTER | INSTEAD OF} triggering_event referencing_clause [WHEN trigger_condition] [FOR EACH ROW] trigger_body;
其中,t r i g g e r _ n a m e是觸發器的名稱,t r i g g e r i n g _ e v e n t說明了激發觸發器的事件(也可能包 括特殊的表或視圖),t r i g g e r _ b o d y是觸發器的代碼。r e f e r e n c i n g _ c l a u s e用來引用正在處於修改狀 態下的行中的資料,如果在 W H E N子句中指定t r i g g e r _ c o n d i t i o n的話,則首先對該條件求值。觸 發器主體只有在該條件為真值時才運行.
因為DML觸發器對我們開發人員來說是最常用的,所以這裡首先詳細對DML觸發器進行詳細講解:
DML觸發器是由資料庫的INSERT/UPDATE/DELETE操作觸發.該類觸發器可以在上述語句之前或之後執行,也可以每個受影響的行執行一次,所以這些條件組合,那麼可以組合出12種類型的DML觸發器.這裡有一個表給出了DML觸發
表6-1 DML觸發器類型 類 別 值 說 明 語句 I N S E RT、D E L E T E、 定義何種D M L語句激發觸發器 U P D AT E 定時 之前或之後 定義觸發器是在語句運行前或運行後激發 級 行或語句 如果觸發器是行級觸發器,該觸發器就對由觸發語句變更的 每一行激發一次。如果觸發器是語句級的觸發器,則該觸發 器就在語句之前或之後激發一次。行級觸發器是按觸發器定 義中的FOR EACH ROW子句表示的
需要注意的一點是:觸發器是與觸發該類型的語句一起作為一個失誤來啟動並執行.
觸發器是在D M L語句運行時激發的,如果有多個觸發器,執行的順序如下: 1) 如果有語句之前級觸發器的話,先運行該觸發器 2) 對於受語句影響每一行: a. 如果有行之前級觸發器的話,運行該觸發器。 b. 執行該語句本身。 c. 如果有行之後級觸發器的話,運行該觸發器。 3) 如果有語句之後級觸發器的話,運行該觸發器
並且對於行級觸發器,可以通過:NEW和:OLD標誌來訪問正在處理中的行資料. 對於DML觸發器,這兩個標誌符的意義如下:
觸發語句 標識符: o l d 標識符: n e w I N S E RT 無定義-所有欄位為空白N U L L 該語句結束時將插入的值 U P D A E 更新前行的原始值 該語句結束時將更新的值 D E L E T E 行刪除前的原始值 無定義-所有欄位為空白N U L L
注意 標識符 : o l d對I N S E RT語句無定義,而標識符 : n e w對D E L E T E語句無定義。 P L / S Q L編譯器不會對在I N S E RT語句中使用的: o l d和在D E L E T E語句中使用的: n e w標識 符報錯,編譯的結果將使該欄位為空白。同時,我們不能在行級觸發器之後改變 : n e w,其原因是該語句已被處理了。總的來說,對: n e w的修改只能在行級觸發器之前修改。:o l d具有唯讀屬性,只能讀入。
n e w和: o l d只在行級觸發器內部合法。如果企圖引用在語句級觸發器之內的: n e w 或: o l d的話,編譯器將報錯。由於語句級的觸發器只運行一次,即使存在很多被語句處理過的行 的話,n e w和: o l d也沒有定義。編譯器不知道該引用那一行
WHEN子句 W H E N子句只適用於行級觸發器。如果使用該子句的話,觸發器體將只對滿足由 W H E N子 句說明的條件的行執行。W H E N子句的文法是: WHEN trigger_condition 其中,t r i g g e r _ c o n d i t i o n是邏輯運算式。該運算式將為每行求值。 : n e w和:o l d記錄可以在 t r i g g e r _ c o n d i t i o n內部引用,但不需使用冒號。該冒號只在觸發器體內有效。例如,觸發器 C h e c k C r e d i t s的體只在當前的學生得到的學分超出2 0時才運行: CREATE OR REPLACE TRIGGER CheckCredits BEFORE INSERT OR UPDATE OF current_credits ON students FOR EACH ROW WHEN (new.current_credits > 20) BEGIN /* Trigger body goes here. */ END;
觸發器謂語:I N S E RT I N G、U P D AT I N G和D E L E T I N G 觸發器的內部(為不同的 D M L語句激發的觸發器)有三個可用來確認執行何種操作的邏輯表 達式。這些運算式的謂語是 I N S E RT I N G、U P D AT I N G、D E L E T I N G。下面說明了每個謂詞的 含義。 運算式謂語 狀 態 I N S E RT I N G 如果觸發語句是I N S E RT的話,則為真值(T R U E),否則為FA L S E U P D AT I N G 如果觸發語句是U P D AT E的話,則為真值(T R U E),否則為FA L S E D E L E T I N G 如果觸發語句是D E L E T E的話,則為真值(T R U E),否則為FA L S E
ORACLE資料庫觸發器【轉載】