☆→SQL触发器的使用(二)UPDATE触发器的工作过程可将UPDATE语句看成两步操作:即捕获数据前像(before image)的DELETE语句,和捕获数据后像(after image)的INSERT语句。当在定义有触发器的表上执行UPDATE语句时,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。 触发器检查deleted表和inserted表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。 可以使用IF UPDATE语句定义一个监视指定列的数据更新的触发器。这样,就可以让触发器容易的隔离出特定列的活动。当它检测到指定列已经更新时,触发器就会进一步执行适当的动作,例如发出错误信息指出该列不能更新,或者根据新的更新的列值执行一系列的动作语句。 ? 语法 IF UPDATE (<column_name>) 例1 本例阻止用户修改Employees表中的EmployeeID列。 USE Northwind GO CREATE TRIGGER Employee_Update ?????? ON Employees ?????? FOR UPDATE AS IF UPDATE (EmployeeID) BEGIN ?????? RAISERROR ('Transaction cannot be processed.\ ?????? ***** Employee ID number cannot be modified.', 10, 1) ?????? ROLLBACK TRANSACTION END ? ??? INSTEAD OF触发器的工作过程可以在表或视图上指定INSTEAD OF触发器。执行这种触发器就能够替代原始的触发动作。INSTEAD OF触发器扩展了视图更新的类型。对于每一种触发动作(INSERT、UPDATE或 DELETE),每一个表或视图只能有一个INSTEAD OF触发器。 INSTEAD OF触发器被用于更新那些没有办法通过正常方式更新的视图。例如,通常不能在一个基于连接的视图上进行DELETE操作。然而,可以编写一个INSTEAD OF DELETE触发器来实现删除。上述触发器可以访问那些如果视图是一个真正的表时已经被删除的数据行。将被删除的行存储在一个名为deleted的工作表中,就像AFTER触发器一样。相似地,在UPDATE INSTEAD OF触发器或者INSERT INSTEAD OF触发器中,你可以访问inserted表中的新行。 不能在带有WITH CHECK OPTION定义的视图中创建INSTEAD OF触发器。 ? 示例 在本例中,创建了一个德国客户表和一个墨西哥客户表。放置在视图上的INSTEAD OF触发器将把更新操作重新定向到适当的基表上。这时发生的插入是对CustomersGer表的插入而不是对视图的插入。 创建两个包含客户数据的表: SELECT * INTO CustomersGer FROM Customers WHERE Customers.Country = 'Germany' SELECT * INTO CustomersMex FROM Customers WHERE Customers.Country = 'Mexico' GO ? 在该数据上创建视图: CREATE VIEW CustomersView AS SELECT * FROM CustomersGer UNION SELECT * FROM CustomersMex GO ? 创建一个在上述视图上的INSTEAD OF触发器: CREATE TRIGGER Customers_Update2 ON CustomersView INSTEAD OF UPDATE AS DECLARE @Country nvarchar(15) SET @Country = (SELECT Country FROM Inserted) IF @Country = 'Germany' ? BEGIN ?? UPDATE CustomersGer ??? SET CustomersGer.Phone = Inserted.Phone ??? FROM CustomersGer JOIN Inserted ??? ON CustomersGer.CustomerID = Inserted.CustomerID ? END ELSE ? IF @Country = 'Mexico' ? BEGIN ?? UPDATE CustomersMex ??? SET CustomersMex.Phone = Inserted.Phone ??? FROM CustomersMex JOIN Inserted ??? ON CustomersMex.CustomerID = Inserted.CustomerID ? END ? 通过更新视图,测试触发器: UPDATE CustomersView SET Phone = ' 030-007xxxx' SELECT CustomerID, Phone FROM CustomersView SELECT CustomerID, Phone FROM CustomersGer -------------------------------------------- CREATE?TRIGGER?[calT1T2T3]?ON?dbo.DCLB? FOR??INSERT,UPDATE AS update?P SET /* 计算方差的触发器 */ P.T1=(I.P1+I.P2+I.P3+I.P4+I.P5+I.P6), P.T2=(I.Y1+I.Y2+I.Y3+I.Y4+I.Y5+I.Y6?), P.T3=SQRT(P.T1*P.T1+P.T2*P.T2) FROM?DCLB?AS?P?INNER?JOIN?Inserted?AS?I ON?P.SID?=?I.SID 触发器的使用很方便,而且也很简单,重要的是理解inserted过程。可将UPDATE语句看成两步操作:即捕获数据前像(before image)的DELETE语句,和捕获数据后像(after image)的INSERT语句。当在定义有触发器的表上执行UPDATE语句时,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。触发器检查deleted表和inserted表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。 |