SQL2000觸發(fā)器的使用[轉(zhuǎn)]
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
觸發(fā)器是數(shù)據(jù)庫應(yīng)用中的重用工具,它的應(yīng)用很廣泛。這幾天寫一個(gè)化學(xué)數(shù)據(jù)統(tǒng)計(jì)方面的軟件,需要根據(jù)采樣,自動(dòng)計(jì)算方差,在這里,我使用了觸發(fā)器。 [br][br]下面我摘錄了sql server官方教程中的一段關(guān)于觸發(fā)器的文字,確實(shí)有用的一點(diǎn)文字描述。 [br][br]可以定義一個(gè)無論何時(shí)用insert語句向表中插入數(shù)據(jù)時(shí)都會(huì)執(zhí)行的觸發(fā)器。 [br][br]當(dāng)觸發(fā)insert觸發(fā)器時(shí),新的數(shù)據(jù)行就會(huì)被插入到觸發(fā)器表和inserted表中。inserted表是一個(gè)邏輯表,它包含了已經(jīng)插入的數(shù)據(jù)行的一個(gè)副本。inserted表包含了insert語句中已記錄的插入動(dòng)作。inserted表還允許引用由初始化insert語句而產(chǎn)生的日志數(shù)據(jù)。觸發(fā)器通過檢查inserted表來確定是否執(zhí)行觸發(fā)器動(dòng)作或如何執(zhí)行它。inserted表中的行總是觸發(fā)器表中一行或多行的副本。 [br][br]日志記錄了所有修改數(shù)據(jù)的動(dòng)作(insert、update和delete語句),但在事務(wù)日志中的信息是不可讀的。然而,inserted表允許你引用由insert語句引起的日志變化,這樣就可以將插入數(shù)據(jù)與發(fā)生的變化進(jìn)行比較,來驗(yàn)證它們或采取進(jìn)一步的動(dòng)作。也可以直接引用插入的數(shù)據(jù),而不必將它們存儲(chǔ)到變量中。 [br][br]示例 [br][br]在本例中,將創(chuàng)建一個(gè)觸發(fā)器。無論何時(shí)訂購產(chǎn)品(無論何時(shí)向order details表中插入一條記錄),這個(gè)觸發(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ā)器后,從受影響的表中刪除的行將被放置到一個(gè)特殊的deleted表中。deleted表是一個(gè)邏輯表,它保留已被刪除數(shù)據(jù)行的一個(gè)副本。deleted表還允許引用由初始化delete語句產(chǎn)生的日志數(shù)據(jù)。 [br][br]使用delete觸發(fā)器時(shí),需要考慮以下的事項(xiàng)和原則: [br][br]·當(dāng)某行被添加到deleted表中時(shí),它就不再存在于數(shù)據(jù)庫表中;因此,deleted表和數(shù)據(jù)庫表沒有相同的行。 [br][br]·創(chuàng)建deleted表時(shí),空間是從內(nèi)存中分配的。deleted表總是被存儲(chǔ)在高速緩存中。 [br][br]·為delete動(dòng)作定義的觸發(fā)器并不執(zhí)行truncate table語句,原因在于日志不記錄truncate table語句。 [br][br]示例 [br][br]在本例中,將創(chuàng)建一個(gè)觸發(fā)器,無論何時(shí)刪除一個(gè)產(chǎn)品類別(即從categories表中刪除一條記錄),該觸發(fā)器都會(huì)更新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語句時(shí),原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。 [br][br]觸發(fā)器檢查deleted表和inserted表以及被更新的表,來確定是否更新了多行以及如何執(zhí)行觸發(fā)器動(dòng)作。 [br][br]可以使用if update語句定義一個(gè)監(jiān)視指定列的數(shù)據(jù)更新的觸發(fā)器。這樣,就可以讓觸發(fā)器容易的隔離出特定列的活動(dòng)。當(dāng)它檢測(cè)到指定列已經(jīng)更新時(shí),觸發(fā)器就會(huì)進(jìn)一步執(zhí)行適當(dāng)?shù)膭?dòng)作,例如發(fā)出錯(cuò)誤信息指出該列不能更新,或者根據(jù)新的更新的列值執(zhí)行一系列的動(dòng)作語句。 [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ā)動(dòng)作。instead of觸發(fā)器擴(kuò)展了視圖更新的類型。對(duì)于每一種觸發(fā)動(dòng)作(insert、update或 delete),每一個(gè)表或視圖只能有一個(gè)instead of觸發(fā)器。 [br][br]instead of觸發(fā)器被用于更新那些沒有辦法通過正常方式更新的視圖。例如,通常不能在一個(gè)基于連接的視圖上進(jìn)行delete操作。然而,可以編寫一個(gè)instead of delete觸發(fā)器來實(shí)現(xiàn)刪除。上述觸發(fā)器可以訪問那些如果視圖是一個(gè)真正的表時(shí)已經(jīng)被刪除的數(shù)據(jù)行。將被刪除的行存儲(chǔ)在一個(gè)名為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)建了一個(gè)德國客戶表和一個(gè)墨西哥客戶表。放置在視圖上的instead of觸發(fā)器將把更新操作重新定向到適當(dāng)?shù)幕砩稀_@時(shí)發(fā)生的插入是對(duì)customersger表的插入而不是對(duì)視圖的插入。 [br][br]創(chuàng)建兩個(gè)包含客戶數(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)建一個(gè)在上述視圖上的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]通過更新視圖,測(cè)試觸發(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]那么具體的講,對(duì)于多列數(shù)據(jù),如何計(jì)算方差呢?: [br][br]create trigger [calt1t2t3] on dbo.dclb [br]for insert,update [br]as [br]update p [br]set [br]/**//* [br]計(jì)算方差的觸發(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ā)器的使用很方便,而且也很簡(jiǎn)單,重要的是理解inserted過程??蓪pdate語句看成兩步操作:即捕獲數(shù)據(jù)前像(before image)的delete語句,和捕獲數(shù)據(jù)后像(after image)的insert語句。當(dāng)在定義有觸發(fā)器的表上執(zhí)行update語句時(shí),原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。觸發(fā)器檢查deleted表和inserted表以及被更新的表,來確定是否更新了多行以及如何執(zhí)行觸發(fā)器動(dòng)作。 [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)文章
正在查詢... |