1、簡介
觸發器(trigger)是個特殊的存儲過程,它的執行不是由程序調用,也不是手工啟動,而是由事件來觸發,比如當對一個表或者視圖進行操作( insert,delete, update)時就會激活它執行。觸發器經常用于加強數據的完整性約束和業務規則等。
觸發器也可用于強制引用完整性,以便在多個表中添加、更新或刪除行時,保留在這些表之間所定義的關系。然而,強制引用完整性的最好方法是在相關表中定義主鍵和外鍵約束。如果使用數據庫關系圖,則可以在表之間創建關系以自動創建外鍵約束。
在觸發器中的操作可以是insert、update、delete、execute procedure或execute function操作。
在一個表或視圖上,可以有多個insert、update、select或delete的觸發器。
2、重要概念
1)觸發器名稱
標識一個觸發器,并在在數據庫中必須保持唯一性。
2)觸發事件
i) 數據庫語句能啟動觸發器。觸發的事件可以是insert、update、delete或select語句;
ii)在update或select事件中,在觸發時可加上一個多個字段作為觸發條件;
iii)在insert或delete事件中,任何一個在表上的insert或delete操作都可以觸發觸發器;
iv)觸發器創建在本地表或視圖中。它不能被創建在遠程數據庫的表或視圖中。
3)觸發的動作
i) 觸發的動作指的是當觸發事件發生時,執行的一些SQL語句;
ii)有三種類型的觸發動作:before、after和for each row;
iii)before觸發動作在觸發器事件發生之前執行;
iv)after觸發動作在觸發事件發生之后執行;
v)for each row觸發動作影響觸發事件發生的所有記錄之上;
vi)觸發動作可以是insert、update、delete、execute procedure或execute function語句。
3、觸發器實例
1)delete觸發器
CREATE TRIGGER delete_customer
DELETE ON customer -- 觸發事件
BEFORE ( EXECUTE PROCEDURE log_customer_proc( ) ); -- 觸發動作
上面的實例在customer表中創建了一個名為delete_customer的delete類型的觸發器。這個觸發器將在customer中的一條或者多條數據做刪除操作時被執行。當這個觸發器被觸發時,在這之前需要執行log_customer_proc存儲過程來記錄日志。
2)update觸發器
CREATE TRIGGER update_unit_price
UPDATE OF unit_price ON stock -- 觸發事件 REFERENCING OLD AS pre NEW AS post
FOR EACH ROW WHEN (post.unit_price > pre.unit_price * 2)
( INSERT INTO warn_table VALUES(pre.stock_num, pre.manu_code,
pre.unit_price, post.unit_price, CURRENT) ); -- 觸發動作
這個實例在stock表中創建了一個名為update_unit_price的update觸發器。這個觸發器會在unit_price字段被更新時執行。當這個觸發器起作用的時候,觸發器的動作將在每一條滿足post.unit_price > pre.unit_price*2條件時的記錄。
3)select的觸發器
CREATE TRIGGER select_customer_num
SELECT OF num ON customer -- 觸發事件
REFERENCING OLD AS pre
FOR EACH ROW
(INSERT INTO scn_log VALUES (pre.num, CURRENT, USER) ); -- 觸發動作
這個實例在customer表上創建了一個名為select_customer的select觸發器。這個觸發器將在在num列被查詢的時候被執行。對每條被影響的行都進行如下的操作:
INSERT INTO scn_log VALUES (pre.num, CURRENT, USER);
4)insert的觸發器
CREATE TRIGGER insert_customer
INSERT ON customer -- 觸發事件
REFERENCING NEW AS post
FOR EACH ROW
(INSERT INTO customer_summary VALUES (post.num, post.name)); -- 觸發動作
這個實例在customer表中創建了一個名為insert_customer的insert類型的觸發器。這個觸發器影響在customer表中插入的每一行。在該表記錄插入時,觸發器附加執行了如下操作:
INSERT INTO customer_summary VALUES (post.num, post.name);
5)觸發存儲過程
在該實例中展示如何在觸發器中調用存儲過程,例如如下創建了items_trigger_proc的存儲過程:
CREATE PROCEDURE items_trigger_proc()
REFERENCING OLD AS pre NEW AS post FOR items;
if (SELECTING) then
insert into log_records values (1, pre.quantity, -1);
end if
if (INSERTING) then
insert into log_records values (2, -1, post.quantity);
end if
if (DELETING) then
insert into log_records values (3, pre.quantity, -1);
end if
if (UPDATING) then
insert into log_records values (4, pre.quantity, post.quantity);
end if
END PROCEDURE;
接著創建update_quantity的觸發器,調用item_trigger_proc存儲過程,參考語句如下:
CREATE TRIGGER update_quantity
UPDATE OF quantity ON items
FOR EACH ROW
(EXECUTE PROCEDURE items_trigger_proc()
WITH TRIGGER REFERENCES);
4、觸發器的優點
觸發器可通過數據庫中的相關表實現級聯更改;不過,通過級聯引用完整性約束可以更有效地執行這些更改。觸發器可以強制比用 CHECK 約束定義的約束更為復雜的約束。與 CHECK 約束不同,觸發器可以引用其它表中的列。例如,觸發器可以使用另一個表中的 SELECT 比較插入或更新的數據,以及執行其它操作,如修改數據或顯示用戶定義錯誤信息。觸發器也可以評估數據修改前后的表狀態,并根據其差異采取對策。一個表中的多個同類觸發器(INSERT、UPDATE 或 DELETE)允許采取多個不同的對策以響應同一個修改語句。
posted on 2010-11-05 16:42
阿蜜果 閱讀(2532)
評論(0) 編輯 收藏 所屬分類:
database