1、SQL Server 2000 中的触发器使用(good)文库.txt 我的优点是:我很帅;但是我的缺点是:我帅的不明显。什么是幸福?幸福就是猫吃鱼,狗吃肉,奥特曼打小怪兽!令堂可是令尊表姐?我是胖人,不是粗人。 SQL Server 2000 中的触发器使用(good)触发器是数据库应用中的重用工具,它的应用很广泛。 1. INSERT 触发器的工作过程可以定义一个无论何时用 INSERT 语句向表中插入数据时都会执行的触发器。当触发 INSERT 触发器时,新的数据行就会被插入到触发器表和 inserted 表中。inserted 表是一个逻辑表,它包含了已经插入的数据行的一个副本。ins
2、erted 表包含了INSERT 语句中已记录的插入动作。inserted 表还允许引用由初始化 INSERT 语句而产生的日志数据。触发器通过检查 inserted 表来确定是否执行触发器动作或如何执行它。inserted表中的行总是触发器表中一行或多行的副本。日志记录了所有修改数据的动作(INSERT、UPDATE 和 DELETE 语句),但在事务日志中的信息是不可读的。然而,inserted 表允许你引用由 INSERT 语句引起的日志变化,这样就可以将插入数据与发生的变化进行比较,来验证它们或采取进一步的动作。也可以直接引用插入的数据,而不必将它们存储到变量中。示例在本例中,将创建一
3、个触发器。无论何时订购产品(无论何时向 Order Details 表中插入一条记录) ,这个触发器都将更新 Products 表中的一列(UnitsInStock)。用原来的值减去订购的数量值即为新值。USE NorthwindCREATE TRIGGER OrdDet_InsertON Order DetailsFOR INSERTASUPDATE P SETUnitsInStock = P.UnitsInStock I.QuantityFROM Products AS P INNER JOIN Inserted AS ION P.ProductID = I.ProductID2. DEL
4、ETE 触发器的工作过程当触发 DELETE 触发器后,从受影响的表中删除的行将被放置到一个特殊的 deleted 表中。deleted 表是一个逻辑表,它保留已被删除数据行的一个副本。deleted 表还允许引用由初始化 DELETE 语句产生的日志数据。使用 DELETE 触发器时,需要考虑以下的事项和原则:当某行被添加到 deleted 表中时,它就不再存在于数据库表中;因此,deleted 表和数据库表没有相同的行。创建 deleted 表时,空间是从内存中分配的。deleted 表总是被存储在高速缓存中。为 DELETE 动作定义的触发器并不执行 TRUNCATE TABLE 语句,
5、原因在于日志不记录TRUNCATE TABLE 语句。示例在本例中,将创建一个触发器,无论何时删除一个产品类别(即从 Categories 表中删除一条记录) ,该触发器都会更新 Products 表中的 Discontinued 列。所有受影响的产品都标记为 1,标示不再使用这些产品了。USE NorthwindCREATE TRIGGER Category_DeleteON CategoriesFOR DELETEASUPDATE P SET Discontinued = 1FROM Products AS P INNER JOIN deleted AS dON P.CategoryID
6、= d.CategoryID3. UPDATE 触发器的工作过程可将 UPDATE 语句看成两步操作:即捕获数据前像(before image)的 DELETE 语句,和捕获数据后像(after image)的 INSERT 语句。当在定义有触发器的表上执行 UPDATE 语句时,原始行(前像)被移入到 deleted 表,更新行(后像)被移入到 inserted 表。触发器检查 deleted 表和 inserted 表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。可以使用 IF UPDATE 语句定义一个监视指定列的数据更新的触发器。这样,就可以让触发器容易的隔离出特定列的活
7、动。当它检测到指定列已经更新时,触发器就会进一步执行适当的动作,例如发出错误信息指出该列不能更新,或者根据新的更新的列值执行一系列的动作语句。语法: IF UPDATE ()本例阻止用户修改 Employees 表中的 EmployeeID 列。USE NorthwindGOCREATE TRIGGER Employee_UpdateON EmployeesFOR UPDATEASIF UPDATE (EmployeeID)BEGIN RAISERROR (Transaction cannot be processed.* Employee ID number cannot be modifi
8、ed., 10, 1)ROLLBACK TRANSACTIONEND4. INSTEAD OF 触发器的工作过程可以在表或视图上指定 INSTEAD OF 触发器。执行这种触发器就能够替代原始的触发动作。INSTEAD OF 触发器扩展了视图更新的类型。对于每一种触发动作(INSERT、UPDATE 或 DELETE),每一个表或视图只能有一个 INSTEAD OF 触发器。INSTEAD OF 触发器被用于更新那些没有办法通过正常方式更新的视图。例如,通常不能在一个基于连接的视图上进行 DELETE 操作。然而,可以编写一个 INSTEAD OF DELETE 触发器来实现删除。上述触发器可
9、以访问那些如果视图是一个真正的表时已经被删除的数据行。将被删除的行存储在一个名为 deleted 的工作表中,就像 AFTER 触发器一样。相似地,在UPDATE INSTEAD OF 触发器或者 INSERT INSTEAD OF 触发器中,你可以访问 inserted 表中的新行。不能在带有 WITH CHECK OPTION 定义的视图中创建 INSTEAD OF 触发器。示例在本例中,创建了一个德国客户表和一个墨西哥客户表。放置在视图上的 INSTEAD OF触发器将把更新操作重新定向到适当的基表上。这时发生的插入是对 CustomersGer 表的插入而不是对视图的插入。创建两个包含
10、客户数据的表:SELECT * INTO CustomersGer FROM Customers WHERE Customers.Country = GermanySELECT * INTO CustomersMex FROM Customers WHERE Customers.Country = MexicoGO在该数据上创建视图:CREATE VIEW CustomersView ASSELECT * FROM CustomersGerUNIONSELECT * FROM CustomersMexGO创建一个在上述视图上的 INSTEAD OF 触发器:CREATE TRIGGER Cus
11、tomers_Update2ON CustomersViewINSTEAD OF UPDATE ASDECLARE Country nvarchar(15)SET Country = (SELECT Country FROM Inserted)IF Country = GermanyBEGINUPDATE CustomersGerSET CustomersGer.Phone = Inserted.PhoneFROM CustomersGer JOIN InsertedON CustomersGer.CustomerID = Inserted.CustomerIDENDELSEIF Countr
12、y = MexicoBEGINUPDATE CustomersMexSET CustomersMex.Phone = Inserted.PhoneFROM CustomersMex JOIN InsertedON CustomersMex.CustomerID = Inserted.CustomerIDEND通过更新视图,测试触发器:UPDATE CustomersView SET Phone = 030-007xxxx WHERE CustomerID = ALFKISELECT CustomerID, Phone FROM CustomersView WHERE CustomerID =
13、ALFKISELECT CustomerID, Phone FROM CustomersGer WHERE CustomerID = ALFKI那么具体的讲,对于多列数据,如何计算方差呢?:CREATE TRIGGER calT1T2T3 ON dbo.DCLB FOR INSERT,UPDATEASupdate PSET/*/*计算方差的触发器*/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 ION P.SID = I.SID触发器的使用很方便,而且也很简单,重要的是理解 inserted 过程。可将 UPDATE 语句看成两步操作:即捕获数据前像(before image)的 DELETE 语句,和捕获数据后像(after image)的 INSERT 语句。当在定义有触发器的表上执行 UPDATE 语句时,原始行(前像)被移入到 deleted 表,更新行(后像)被移入到 inserted 表。触发器检查 deleted 表和inserted 表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。