概念
觸發器是在事件發生時隱式地自動運行的PL/SQL程式塊,不能接收參數,不能被調用。
構成
觸發器名稱
觸發器的觸發條件
觸發器限制
觸發器主體
語法
CREATE[ORREPLACE]TRIGGERtrigger_name
{BEFORE|AFTER|INSTEADOF}triggering_event
[WHENtrigger_condition]--限制條件
[FOREACHROW]--行級觸發
說明
triggering_event說明了激發觸發器的事件(也可能包括特殊的表或視圖)。
trigger_body是觸發器的代碼。
如果在WHEN子句中指定trigger_condition的話,則首先對該條件求值。觸發器主體只有在該條件為真值時才運行。
DML觸發器是針對某個表進行DML操作時觸發的。
DML=Data Manipulation Language(數據操縱語言)
格式
CREATE[ORREPLACE]TRIGGERtrigger_name
{BEFORE|AFTER}
{INSERT|DELETE|UPDATE[OFcolumn[,column…]]}ON{table_name|view_name}
[REFERENCING
{OLD[AS]old_name|NEW[AS]new_name}]
[FOREACHROW]
[WHENtrigger_condition]
trigger_body;
觸發器類型.
1、語句級觸發器
語句級觸發器在每個數據修改語句執行後只調用一次,而不管這一操作將影響到多少行。
例1:創建一個orderdetails_tablelog表及一個AFTER觸發器,用於記錄是哪些用戶刪除了orderdetails表中的數據及刪除的時間。
--先創建表
createtableorderdetails_tablelog
(
whovarchar2(40),
oper_datedate
);
--再做觸發器
createorreplacetriggerdele_orderdetails
afterdeleteonorderdetails
begin
insertintoorderdetails_tablelog (who,oper_date) values(user,sysdate);
end;
注意:在該觸發器被觸發後,儘管一次刪除多條記錄,但是觸發器只執行一次插入操作;
例2:創建一個 BEFORE 觸發器,使得在向 ORDERS 表中插入記錄之前對 ShippedDate欄位進行檢測, 要求其值不允許為周六或周日,發貨時間應在8-18點之間.否則將提示錯誤’發貨時間應為工作時間’.
create or replace trigger secure_shippeddate
before insert on orders
for each row
begin
if
(to_char(:new.shippeddate,’dy’)in('星期六','星期日'))
or
(to_number(to_char(:new.shippeddate,’hh24’))not between 8 and 18)
then
raise_application_error(-20500,’發貨時間應為工作時間’);
endif;
end;
2、多條件觸發器
CREATEORREPLACETRIGGER…
BEFOREinsertorupdateordelete
ON…
BEGIN
IFINSERTINGTHEN
…
ENDIF;
IFDELETINGTHEN
…
ENDIF;
IFUPDATINGTHEN
…
ENDIF;
End;
例3:創建一個多條件觸發器,用於實現記錄用戶對產品表進行的操作類型,操作時間,用戶名(創建一個prod_operate_log表記載信息,其中操作編號自動增長).
1)創建prod_operate_log表
CREATETABLEprod_operate_log
(OperIDnumber,
usernamevarchar2(200),
Operate_datetimestamp,
Operate_typevarchar2(10)
);
2)創建序列logID
CREATESEQUENCElogID
STARTWITH1
INCREMENTBY1
NOMAXVALUE
CACHE10;
3、級聯觸發器
把一個資料庫觸發器的動作與另一個觸發器聯繫起來,使之觸發另一個觸發器。
例4:創建3個表A、B、C,在表A上設定一個INSERT觸發器,用於向表B添加一條記錄,在表B上設定一個INSERT觸發器,用於向表C添加一條記錄,,在表C上設定一個INSERT觸發器,用於對A表中的所有記錄進行更新(+10)
創建A、B、C三張表
CREATETABLEA(AIDnumber);
CREATETABLEB(BIDnumber);
CREATETABLEC(CIDnumber);
創建觸發器表
--在表A上創建INSERT觸發器
CREATEORREPLACETRIGGERinsert_a
AFTERinsertONA
Begin
insertintobvalues(1);
End;
--在表B上創建INSERT觸發器
CREATEORREPLACETRIGGERinsert_b
AFTERinsertONB
Begin
insertintocvalues(2);
End;
-在表C上創建INSERT觸發器
CREATEORREPLACETRIGGERinsert_c
AFTERinsertONC
BEGIN
UPDATEa
SETaid=aid+10;
End;
--測試,向A表插入數據5
INSERTINTOAVALUES(5);
4、行級觸發器
行級觸發器是按觸發語句所處理的行激發的,可以引用受到影響的行值。創建觸發器時採用關鍵字FOREACHROW
這種訪問是通過兩個相關的標識符實現的
:old:用於存放未進行修改前的數據
:new:用於存放進行修改後的數據
例5:修改 orderdetails_tablelog 表,增加兩列 orderid,productid,並創建一個 after 觸發器,用於記錄是哪些用戶在什麼時間刪除了 orderdetails 表中的哪些數據。
--先增加兩列
alter table orderdetails_tablelog add orderid number;
alter table orderdetails_tablelog add productid number;
--再做觸發器
create or replace trigger dele_orderdetails
after delete on orderdetails
for each row
begin
insert into orderdetails_tablelog(who,oper_date,orderid,productid)
values(user,sysdate,:old.orderid,:old.productid);
end;