日期:2014-05-17 浏览次数:20643 次
--instead of 触发器和 after --最好是看帮助 if object_id('tb') is not null drop table tb go create table tb(id int) go create trigger tri_tb on tb instead of insert as begin --操作前执行,因为没写任何代码,所以没有插入到表tb任何记录 print '0 rows' end insert into tb select 1 select * from tb --0行 ---------------------------------------- create trigger tri_tb2 on tb after insert as begin --操作后执行,插入动作已经完成,这里可以通过取 inserted表的记录,插入到其他表或更新其他表 print '1 rows' end insert into tb select 1 select * from tb --1行
------解决方案--------------------
AFTER
指定触发器只有在触发 SQL 语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。
如果仅指定 FOR 关键字,则 AFTER 是默认设置。
不能在视图上定义 AFTER 触发器。
INSTEAD OF
指定执行触发器而不是执行触发 SQL 语句,从而替代触发语句的操作。
在表或视图上,每个 INSERT、UPDATE 或 DELETE 语句最多可以定义一个 INSTEAD OF 触发器。然而,可以在每个具有 INSTEAD OF 触发器的视图上定义视图。
INSTEAD OF 触发器不能在 WITH CHECK OPTION 的可更新视图上定义
------解决方案--------------------
INSTEAD OF 可以理解为代替操作,代替插入,代替删除。 当捕捉到INSERT命令时,执行的是代码内指定的内容,而不是真实插入的内容。 举个例子说明吧: create trigger my_tr on v_tb instead of insert as insert t1(col1,col2) select 2,3 go 不管你插入任何数据在v_tb中,最终插入到t1表的数据是2,3这两个。 create trigger my_tr on v_tb instead of insert as insert t1(col1,col2) select col1,col2 from inserted go 如果这样,最终插入到T1的数据就和你在插入v_tb中是一样的。 delete只是动作不同,原理相同。
------解决方案--------------------
这段看看是有必要的
如果 INSTEAD OF INSERT 视图触发器使用 inserted 表中的数据对基表生成 INSERT,则它应当通过排除 INSERT 语句选择列表中的列忽略这些类型的列值。INSERT 语句可为这些类型的列生成虚值。 例如,因为 INSERT 语句必须为映射到基表中标识列或计算列的视图列指定值,所以它可提供占位符值。INSTEAD OF 触发器在构成将值插入基表的 INSERT 语句时会忽略提供的值。 下面的语句创建表、视图和触发器,以解释这一过程: CREATE TABLE BaseTable (PrimaryKey int IDENTITY(1,1) Color nvarchar(10) NOT NULL, Material nvarchar(10) NOT NULL, ComputedCol AS (Color + Material) ) GO --Create a view that contains all columns from the base table. CREATE VIEW InsteadView AS SELECT PrimaryKey, Color, Material, ComputedCol FROM BaseTable GO --Create an INSTEAD OF INSERT trigger on the view. CREATE TRIGGER InsteadTrigger on InsteadView INSTEAD OF INSERT AS BEGIN --Build an INSERT statement ignoring inserted.PrimaryKey and --inserted.ComputedCol. INSERT INTO BaseTable SELECT Color, Material FROM inserted END GO 直接引用 BaseTable 的 INSERT 语句不能为 PrimaryKey 和 ComputedCol 列提供值。例如: --A correct INSERT statement that skips the PrimaryKey and ComputedCol columns. INSERT INTO BaseTable (Color, Material) VALUES (N'Red', N'Cloth') --View the results of the INSERT statement. SELECT PrimaryKey, Color, Material, ComputedCol FROM BaseTable --An incorrect statement that tries to supply a value for the --PrimaryKey and ComputedCol columns. INSERT INTO BaseTable VALUES (2, N'Green', N'Wood', N'GreenWood') 然而,引用 InsteadView 的 INSERT 语句必须为 PrimaryKey 和 ComputedCol 列提供值: --A correct INSERT statement supplying dummy values for the --PrimaryKey and ComputedCol columns. INSERT INTO InsteadView (PrimaryKey, Color, Material, ComputedCol) VALUES (999, N'Blue', N'Plastic', N'XXXXXX') --View the results of the INSERT statement. SELECT PrimaryKey, Color, Material, ComputedCol FROM InsteadView 传递到 InsteadTrigger 的 inserted 表由不可为空的 PrimaryKey 和 ComputedCol 列构成,所以引用该视图的 INSERT 语句必须提供那些列的值。值 999 和 N'XXXXXX' 传递到 InsteadTrigger,但是触发器中的 INSERT 语句没有选择 inserted、PrimaryKey 或 ComputedCol,因此忽略该值。实际插入 BaseTable 的行在 PrimaryKey 中有 2,在 ComputedCol