ORACLE数据库触发器
ORACLE?觸發(fā)器其實是PL/SQL塊,它類似于存儲過程和函數(shù),不過有一點不同的是,觸發(fā)器是隱式調(diào)用的,并不能接收參數(shù).?? ?ORACLE觸發(fā)器有三種類型,分別是:DML觸發(fā)器, 替代觸發(fā)器和系統(tǒng)觸發(fā)器. 下面對這三種類型一一進行講述
?1.DML觸發(fā)器
? 顧名思義,DML觸發(fā)器是由DML語句觸發(fā)的.例如數(shù)據(jù)庫的INSERT/UPDATE/DELETE操作都可以觸發(fā)該類型的觸發(fā)器. 它們可以在這些語句之前或之后觸發(fā),或者在行級上觸發(fā)(就是說對于每個受影響的行都觸發(fā)一次)
?例如我們有一張表TABLE1 ,總共有三個字段??ID,姓名,年齡 ,當(dāng)我們在插入時希望ID可以自動生成,那么可以建立一個觸發(fā)器
?
CREATE?OR?REPLACE?TRIGGER?TR_INSERT_ID?BEFORE?INSERT?ON??TABLE1
BEGIN
?SELECT??T.NEXTVAL?INTO?:NEW.ID?FROM?DUAL;
END;
?
那么當(dāng)我們插入該表的時候,ID字段會自動填充.
2.替代觸發(fā)器
替代觸發(fā)器只能使用在視圖上,與DML不同的是,DML觸發(fā)器是運行在DML之外的,而替代觸發(fā)器是代替激發(fā)它的DML語句運行.替代觸發(fā)器是行級,舉個例子,這里有個視圖:
--例子來源insteadOf.sql
?
CREATE?OR?REPLACE?VIEW?classes_rooms?ASSELECT?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
觸發(fā)器,那么就可以解決這個問題:
?
CREATE?TRIGGER?ClassesRoomsInsertINSTEAD?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;
該觸發(fā)器就可以正常工作了
3.系統(tǒng)觸發(fā)器
這種觸發(fā)器是發(fā)生在如數(shù)據(jù)庫啟動或關(guān)閉等系統(tǒng)事件時,不是在執(zhí)行DML語句時發(fā)生,當(dāng)然也可以在DDL時觸發(fā).
?
不管是以上三種的哪一種,創(chuàng)建的語法都是一致的.
?
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是觸發(fā)器的名稱,t r i g g e r i n g _ e v e n t說明了激發(fā)觸發(fā)器的事件(也可能包
括特殊的表或視圖),t r i g g e r _ b o d y是觸發(fā)器的代碼。r e f e r e n c i n g _ c l a u s e用來引用正在處于修改狀
態(tài)下的行中的數(shù)據(jù),如果在 W H E N子句中指定t r i g g e r _ c o n d i t i o n的話,則首先對該條件求值。觸
發(fā)器主體只有在該條件為真值時才運行.
因為DML觸發(fā)器對我們開發(fā)人員來說是最常用的,所以這里首先詳細對DML觸發(fā)器進行詳細講解:
?DML觸發(fā)器是由數(shù)據(jù)庫的INSERT/UPDATE/DELETE操作觸發(fā).該類觸發(fā)器可以在上述語句之前或之后執(zhí)行,也可以每個受影響的行執(zhí)行一次,所以這些條件組合,那么可以組合出12種類型的DML觸發(fā)器.這里有一個表給出了DML觸發(fā)
???????????? 表6-1?? DML觸發(fā)器類型
類 別????????????????????????????????? ?值??????????????????????????????????????????? ? 說 明
語句????????????????????? I N S E RT、D E L E T E、???? ?定義何種D M L語句激發(fā)觸發(fā)器
???????????????????????????? U P D AT E
定時?????????????????????? 之前或之后?????????????????????????????? 定義觸發(fā)器是在語句運行前或運行后激發(fā)
級?????????????????????? 行或語句???????????????????????????????????? 如果觸發(fā)器是行級觸發(fā)器,該觸發(fā)器就對由觸發(fā)語句變更的
??????????????????????????????????????????????????????????????????????????????? 每一行激發(fā)一次。如果觸發(fā)器是語句級的觸發(fā)器,則該觸發(fā)
??????????????????????????????????????????????????????????????????????????????? 器就在語句之前或之后激發(fā)一次。行級觸發(fā)器是按觸發(fā)器定
?????????????????????????????????????????????????????????????????????????????? 義中的FOR EACH ROW子句表示的
需要注意的一點是:觸發(fā)器是與觸發(fā)該類型的語句一起作為一個失誤來運行的.
觸發(fā)器是在D M L語句運行時激發(fā)的,如果有多個觸發(fā)器,執(zhí)行的順序如下:
1) 如果有語句之前級觸發(fā)器的話,先運行該觸發(fā)器
2) 對于受語句影響每一行:
a. 如果有行之前級觸發(fā)器的話,運行該觸發(fā)器。
b. 執(zhí)行該語句本身。
c. 如果有行之后級觸發(fā)器的話,運行該觸發(fā)器。
3) 如果有語句之后級觸發(fā)器的話,運行該觸發(fā)器
并且對于行級觸發(fā)器,可以通過:NEW和:OLD標志來訪問正在處理中的行數(shù)據(jù). 對于DML觸發(fā)器,這兩個標志符的意義如下:
觸發(fā)語句?????????????????????????? 標識符: o l d????????????????????????????????????????? ?標識符: n e w
I N S E RT?????????? 無定義-所有字段為空N U L L?????????????????? ?該語句結(jié)束時將插入的值
U P D A E???????????????? 更新前行的原始值?????????????????????????????? 該語句結(jié)束時將更新的值
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標識
符報錯,編譯的結(jié)果將使該字段為空。同時,我們不能在行級觸發(fā)器之后改變 : n e w,其原因是該語句已被處理了。總的來說,對: n e w的修改只能在行級觸發(fā)器之前修改。:o l d具有只讀屬性,只能讀入。
n e w和: o l d只在行級觸發(fā)器內(nèi)部合法。如果企圖引用在語句級觸發(fā)器之內(nèi)的: n e w
或: o l d的話,編譯器將報錯。由于語句級的觸發(fā)器只運行一次,即使存在很多被語句處理過的行
的話,n e w和: o l d也沒有定義。編譯器不知道該引用那一行
?
WHEN子句
W H E N子句只適用于行級觸發(fā)器。如果使用該子句的話,觸發(fā)器體將只對滿足由 W H E N子
句說明的條件的行執(zhí)行。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內(nèi)部引用,但不需使用冒號。該冒號只在觸發(fā)器體內(nèi)有效。例如,觸發(fā)器
C h e c k C r e d i t s的體只在當(dāng)前的學(xué)生得到的學(xué)分超出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;
?觸發(fā)器謂語:I N S E RT I N G、U P D AT I N G和D E L E T I N G
觸發(fā)器的內(nèi)部(為不同的 D M L語句激發(fā)的觸發(fā)器)有三個可用來確認執(zhí)行何種操作的邏輯表
達式。這些表達式的謂語是 I N S E RT I N G、U P D AT I N G、D E L E T I N G。下面說明了每個謂詞的
含義。
表達式謂語?????????????????????????????????????? 狀 態(tài)
I N S E RT I N G???? 如果觸發(fā)語句是I N S E RT的話,則為真值(T R U E),否則為FA L S E
U P D AT I N G??? 如果觸發(fā)語句是U P D AT E的話,則為真值(T R U E),否則為FA L S E
D E L E T I N G??? 如果觸發(fā)語句是D E L E T E的話,則為真值(T R U E),否則為FA L S E
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/lovingprince/archive/2007/03/24/2166456.html
總結(jié)
以上是生活随笔為你收集整理的ORACLE数据库触发器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .Net PetShop 4.0的缓存处
- 下一篇: 【收集】ADOADO.NET 读取 Or