徐曉麗
在大型關系數(shù)據(jù)庫設計中,會經常用到觸發(fā)器。它的特點是:一旦被定義,就存在于后臺數(shù)據(jù)庫系統(tǒng)(server,服務器方)中,并會在往表中插入記錄、更改記錄或者刪除記錄時,被自動地隱式執(zhí)行,從而使得它的設計既與前臺(client,客戶機方)的平臺無關,又免除了前臺相關的數(shù)據(jù)操作設計。因此,觸發(fā)器可以用來對表實施復雜的完整性約束,當觸發(fā)器所保護的數(shù)據(jù)發(fā)生改變時,觸發(fā)器會自動被激活,從而防止對數(shù)據(jù)的不正確修改。
根據(jù)觸發(fā)器被激活的時機不同,SQL Server 2000中提供了兩種類型的觸發(fā)器:INSTEAD OF觸發(fā)器和AFTER觸發(fā)器[1]。
AFTER觸發(fā)器在一個INSERT、UPDATE或DELETE語句完成之后執(zhí)行,進行約束檢查等動作都將在AFTER觸發(fā)器被激活之前發(fā)生。AFTER觸發(fā)器只能用于表。
INSTEAD OF觸發(fā)器用于替代引起觸發(fā)器執(zhí)行的T-SQL語句。除表之外,INSTEAD OF觸發(fā)器也可以用于視圖,用來擴展視圖可以支持的更新操作。
一個表或視圖的每個修改動作(INSERT、UPDATE和DELETE)都可以有一個INSTEAD OF觸發(fā)器,但可以有多個AFTER觸發(fā)器。
觸發(fā)器主要用于如下幾個方面:自動生成派生列值;禁止非法事務;增強復雜的安全識別; 在分布式數(shù)據(jù)庫中增強參照完整性;增強復雜的商業(yè)規(guī)則;提供透明的事件日志;提供高級審計;維護同步表復制;在表存取上進行聚合統(tǒng)計。開發(fā)人員一般是對上述幾種情況作組合使用,可歸為以下四種典型應用。
(1)對庫中相關表進行連環(huán)更新,如:鍵值的同步更新,數(shù)據(jù)冗余實現(xiàn),計算表的同步更新等;
(2)實現(xiàn)那些破壞完整性操作的拒絕,如:不匹配外鍵值的插入拒絕;
(3)實現(xiàn)庫定義本身所不能實現(xiàn)的更為復雜的商業(yè)規(guī)則,如:更新操作的時間限制,更新數(shù)據(jù)的幅度限制等;
(4)實現(xiàn)簡單的“如果……怎么辦”的分析。
觸發(fā)器的實現(xiàn)離不了以下兩個專用表:Inserted表和Deleted表。這是兩個邏輯表,由系統(tǒng)來維護,用戶不能對它們進行修改。它們存放在內存而不是數(shù)據(jù)庫中。這兩個表的結構總是與激活該觸發(fā)器的表的結構相同。觸發(fā)器執(zhí)行完成后,與該觸發(fā)器相關的這兩個表也會被刪除。
Deleted表存放由于執(zhí)行DELETE或UPDATE語句而要從表中刪除的所有行。在執(zhí)行DELETE或UPDATE操作時,被刪除的行從表中被移動到Deleted表,這兩個表不會有共同的行。
Inserted表存放由于執(zhí)行INSERT或UPDATE語句而要向表中插入的所有行。在 INSERT或UPDATE事務中,新的行同時添加到激活觸發(fā)器的表和Inserted表中,Inserted表的內容是激活觸發(fā)器的表中新行的拷貝。
在創(chuàng)建觸發(fā)器時需要制定以下內容:觸發(fā)器的名稱、觸發(fā)器所基于的表或視圖、觸發(fā)器種類(AFTER 或 INSTEAD OF)、激活觸發(fā)器的修改語句(INSERT、UPDATE和DELETE)、觸發(fā)器執(zhí)行的語句,用T-SQL語句創(chuàng)建觸發(fā)器的具本語法如下:[2]
CREATE Trigger trigger_name
ON {table_name | view_name}
{ AFTER | INSTEAD OF}
[INSERT,UPDATE,DELETE]
AS
Sq_Statement
在一個Market數(shù)據(jù)庫中有Goods表、Customers表及Orders表,三個表的結構如下所示:
Goods:
Customers:
Orders:
現(xiàn)要求當向Orders表中插入一條記錄時,ordersum(訂貨金額)字段的值由quantity*price而得到,并且如課該客戶是重點客戶,則對其打8.5折,若是一般客戶,則不打折。
分析:由于quantity字段和price字段分別來自不同的表中,因此不能在創(chuàng)建表時用公式來完成。為了實現(xiàn)此功能,我們可考慮在Orders中針對Insert操作建立一個INSTEAD OF觸發(fā)器,在觸發(fā)器中查詢下定單的客戶的類別及所定貨品的價格,計算出貨品的ordersum的值;然后再將記錄插入到Orders表中。具體代碼如下所示:
CREATE TRIGGER orderinsert ON OrderS
INSTEAD OF INSERT
AS
declare @price money,@quantity int,@type varchar(10)
declare @sum money
select @price=price,@quantity=quantity,@type=type from goods,inserted,customers where goods.name=inserted.goodsnameandcustomers.customerid=inserted.customerid
if @type='一般客戶'
set @sum=@price*@quantity
else
set @sum=@price*@quantity*0.85
insert into orders(goodsname,customerid,quantity,ordersum,orderdate)select goodsname,customerid,quantity,@sum,orderdate from inserted.
觸發(fā)器建成以后,只有向order表中插入記錄,就會自動計算ordersum字段的值,從而實現(xiàn)了比默認值及公式都更為復雜的字段默認值的設置。
本文通過使用觸發(fā)器,實現(xiàn)了通過幾個表的數(shù)據(jù)對某一字段進行自動計算的功能,完成了比CHECK約束更復雜的限制。當然,也可以通過觸發(fā)器實現(xiàn)數(shù)據(jù)庫的級聯(lián)更新、級聯(lián)刪除及某些字段的自動更新功能(如增加某一訂單時,減少Goods表中相應貨品的庫存量)。綜上所述,觸發(fā)器的主要特點在于,不管何種原因造成數(shù)據(jù)變化,它均能自動響應。觸發(fā)器對數(shù)據(jù)庫開發(fā)過程中遇到的問題,往往會有獨到的解決方法。因此,在當今數(shù)據(jù)庫系統(tǒng)的建立中,系統(tǒng)開發(fā)人員除了使用視圖、存儲過程等技術外,大多也使用觸發(fā)器技術,以改進數(shù)據(jù)庫系統(tǒng)建立的質量,使數(shù)據(jù)庫的設計變得簡潔和高效。
[1]羅運模,王珊等《SQL Server數(shù)據(jù)庫系統(tǒng)基礎》[M].高等教育出版社.
[2][美]James R.Groff Paul N.Weinberg 著.章小莉,寧欣,汪永好.等譯《SQL 完全手冊》[M].電子工業(yè)出版社.
[3]郭勐,張擁軍,彭宇行.數(shù)據(jù)庫觸發(fā)器機制的設計與實現(xiàn)[J].電子技術應用,2005,(02).
[4]莫裕清,SQL Server 2000中基于觸發(fā)器的自動更新[J].中國科技信息.2006 Vol.8 P.221-222.
[5]黃曉濤,數(shù)據(jù)庫觸發(fā)器實現(xiàn)數(shù)據(jù)庫系統(tǒng)的主動功能[J].計算機應用研究.2005 Vol.21 No.2 P.238-240.
[6]周愛華,南理勇.SQL Server 2000數(shù)據(jù)庫觸發(fā)器的應用[J].商場現(xiàn)代化,2008,(07).