SQL2000觸發(fā)器的使用[轉(zhuǎn)]
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
觸發(fā)器是數(shù)據(jù)庫應(yīng)用中的重用工具,它的應(yīng)用很廣泛。這幾天寫一個化學(xué)數(shù)據(jù)統(tǒng)計方面的軟件,需要根據(jù)采樣,自動計算方差,在這里,我使用了觸發(fā)器。 [br][br]下面我摘錄了sql server官方教程中的一段關(guān)于觸發(fā)器的文字,確實有用的一點文字描述。 [br][br]可以定義一個無論何時用insert語句向表中插入數(shù)據(jù)時都會執(zhí)行的觸發(fā)器。 [br][br]當(dāng)觸發(fā)insert觸發(fā)器時,新的數(shù)據(jù)行就會被插入到觸發(fā)器表和inserted表中。inserted表是一個邏輯表,它包含了已經(jīng)插入的數(shù)據(jù)行的一個副本。inserted表包含了insert語句中已記錄的插入動作。inserted表還允許引用由初始化insert語句而產(chǎn)生的日志數(shù)據(jù)。觸發(fā)器通過檢查inserted表來確定是否執(zhí)行觸發(fā)器動作或如何執(zhí)行它。inserted表中的行總是觸發(fā)器表中一行或多行的副本。 [br][br]日志記錄了所有修改數(shù)據(jù)的動作(insert、update和delete語句),但在事務(wù)日志中的信息是不可讀的。然而,inserted表允許你引用由insert語句引起的日志變化,這樣就可以將插入數(shù)據(jù)與發(fā)生的變化進行比較,來驗證它們或采取進一步的動作。也可以直接引用插入的數(shù)據(jù),而不必將它們存儲到變量中。 [br][br]示例 [br][br]在本例中,將創(chuàng)建一個觸發(fā)器。無論何時訂購產(chǎn)品(無論何時向order details表中插入一條記錄),這個觸發(fā)器都將更新products表中的一列(unitsinstock)。用原來的值減去訂購的數(shù)量值即為新值。 [br][br]use northwind [br]create trigger orddet_insert [br]on [order details] [br]for insert [br]as [br]update p set [br]unitsinstock = p.unitsinstock – i.quantity [br]from products as p inner join inserted as i [br]on p.productid = i.productid [br][br]delete觸發(fā)器的工作過程 [br][br]當(dāng)觸發(fā)delete觸發(fā)器后,從受影響的表中刪除的行將被放置到一個特殊的deleted表中。deleted表是一個邏輯表,它保留已被刪除數(shù)據(jù)行的一個副本。deleted表還允許引用由初始化delete語句產(chǎn)生的日志數(shù)據(jù)。 [br][br]使用delete觸發(fā)器時,需要考慮以下的事項和原則: [br][br]·當(dāng)某行被添加到deleted表中時,它就不再存在于數(shù)據(jù)庫表中;因此,deleted表和數(shù)據(jù)庫表沒有相同的行。 [br][br]·創(chuàng)建deleted表時,空間是從內(nèi)存中分配的。deleted表總是被存儲在高速緩存中。 [br][br]·為delete動作定義的觸發(fā)器并不執(zhí)行truncate table語句,原因在于日志不記錄truncate table語句。 [br][br]示例 [br][br]在本例中,將創(chuàng)建一個觸發(fā)器,無論何時刪除一個產(chǎn)品類別(即從categories表中刪除一條記錄),該觸發(fā)器都會更新products表中的discontinued列。所有受影響的產(chǎn)品都標(biāo)記為1,標(biāo)示不再使用這些產(chǎn)品了。 [br][br]use northwind [br]create trigger category_delete [br]on categories [br]for delete [br]as [br]update p set discontinued = 1 [br]from products as p inner join deleted as d [br]on p.categoryid = d.categoryid [br][br]update觸發(fā)器的工作過程 [br][br]可將update語句看成兩步操作:即捕獲數(shù)據(jù)前像(before image)的delete語句,和捕獲數(shù)據(jù)后像(after image)的insert語句。當(dāng)在定義有觸發(fā)器的表上執(zhí)行update語句時,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。 [br][br]觸發(fā)器檢查deleted表和inserted表以及被更新的表,來確定是否更新了多行以及如何執(zhí)行觸發(fā)器動作。 [br][br]可以使用if update語句定義一個監(jiān)視指定列的數(shù)據(jù)更新的觸發(fā)器。這樣,就可以讓觸發(fā)器容易的隔離出特定列的活動。當(dāng)它檢測到指定列已經(jīng)更新時,觸發(fā)器就會進一步執(zhí)行適當(dāng)?shù)膭幼鳎绨l(fā)出錯誤信息指出該列不能更新,或者根據(jù)新的更新的列值執(zhí)行一系列的動作語句。 [br][br]語法 [br][br]if update () [br][br]例1 [br][br]本例阻止用戶修改employees表中的employeeid列。 [br][br]use northwind [br]go [br]create trigger employee_update [br]on employees [br]for update [br]as [br]if update (employeeid) [br]begin [br]raiserror ('transaction cannot be processed.\ [br]***** employee id number cannot be modified.', 10, 1) [br]rollback transaction [br]end [br][br]instead of觸發(fā)器的工作過程 [br][br]可以在表或視圖上指定instead of觸發(fā)器。執(zhí)行這種觸發(fā)器就能夠替代原始的觸發(fā)動作。instead of觸發(fā)器擴展了視圖更新的類型。對于每一種觸發(fā)動作(insert、update或 delete),每一個表或視圖只能有一個instead of觸發(fā)器。 [br][br]instead of觸發(fā)器被用于更新那些沒有辦法通過正常方式更新的視圖。例如,通常不能在一個基于連接的視圖上進行delete操作。然而,可以編寫一個instead of delete觸發(fā)器來實現(xiàn)刪除。上述觸發(fā)器可以訪問那些如果視圖是一個真正的表時已經(jīng)被刪除的數(shù)據(jù)行。將被刪除的行存儲在一個名為deleted的工作表中,就像after觸發(fā)器一樣。相似地,在update instead of觸發(fā)器或者insert instead of觸發(fā)器中,你可以訪問inserted表中的新行。 [br][br]不能在帶有with check option定義的視圖中創(chuàng)建instead of觸發(fā)器。 [br][br]示例 [br][br]在本例中,創(chuàng)建了一個德國客戶表和一個墨西哥客戶表。放置在視圖上的instead of觸發(fā)器將把更新操作重新定向到適當(dāng)?shù)幕砩?。這時發(fā)生的插入是對customersger表的插入而不是對視圖的插入。 [br][br]創(chuàng)建兩個包含客戶數(shù)據(jù)的表: [br][br]select * into customersger from customers where customers.country = 'germany' [br]select * into customersmex from customers where customers.country = 'mexico' [br][br]go [br][br]在該數(shù)據(jù)上創(chuàng)建視圖: [br][br]create view customersview as [br]select * from customersger [br]union [br]select * from customersmex [br]go [br][br]創(chuàng)建一個在上述視圖上的instead of觸發(fā)器: [br][br]create trigger customers_update2 [br][br]on customersview [br][br]instead of update as [br][br]declare @country nvarchar(15) [br][br]set @country = (select country from inserted) [br][br]if @country = 'germany' [br][br]begin [br][br]update customersger [br][br]set customersger.phone = inserted.phone [br][br]from customersger join inserted [br][br]on customersger.customerid = inserted.customerid [br][br]end [br][br]else [br][br]if @country = 'mexico' [br][br]begin [br][br]update customersmex [br][br]set customersmex.phone = inserted.phone [br][br]from customersmex join inserted [br][br]on customersmex.customerid = inserted.customerid [br][br]end [br][br]通過更新視圖,測試觸發(fā)器: [br][br]update customersview set phone = ' 030-007xxxx' [br]where customerid = 'alfki' [br][br]select customerid, phone from customersview [br]where customerid = 'alfki' [br][br]select customerid, phone from customersger [br]where customerid = 'alfki' [br][br]那么具體的講,對于多列數(shù)據(jù),如何計算方差呢?: [br][br]create trigger [calt1t2t3] on dbo.dclb [br]for insert,update [br]as [br]update p [br]set [br]/**//* [br]計算方差的觸發(fā)器 [br]*/ [br]p.t1=(i.p1+i.p2+i.p3+i.p4+i.p5+i.p6), [br]p.t2=(i.y1+i.y2+i.y3+i.y4+i.y5+i.y6 ), [br]p.t3=sqrt(p.t1*p.t1+p.t2*p.t2) [br][br]from dclb as p inner join inserted as i [br]on p.sid = i.sid [br][br]觸發(fā)器的使用很方便,而且也很簡單,重要的是理解inserted過程??蓪pdate語句看成兩步操作:即捕獲數(shù)據(jù)前像(before image)的delete語句,和捕獲數(shù)據(jù)后像(after image)的insert語句。當(dāng)在定義有觸發(fā)器的表上執(zhí)行update語句時,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。觸發(fā)器檢查deleted表和inserted表以及被更新的表,來確定是否更新了多行以及如何執(zhí)行觸發(fā)器動作。 [br]文章來源:[url=http://hi.baidu.com/tsredsun/blog/item/3bf2cdcaae9e6984c8176822.html]http://hi.baidu.com/tsredsun/blog/item/3bf2cdcaae9e6984c8176822.html[/url]
該文章在 2010/6/27 17:34:08 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |