这是一个非常有趣的问题。我正在使用SQL Server2008。我在一个公用表上有两个触发器,例如“ CommonTable”。一个触发器在更新上,另一个在插入/更新/删除上。
--
CREATE TRIGGER [dbo].[Trigger1] ON [dbo].[CommonTable] FOR UPDATE UPDATE [CommonTable] SET [StatusCode] = 'New Value' WHERE [RecId] = 'rec id value'
CREATE TRIGGER [dbo].[Trigger2] ON [dbo].[CommonTable] FOR INSERT, UPDATE, DELETE --based on logic read the value from DELETED or INSERTED table and store in other table. SELECT @RowData = (SELECT * FROM DELETED AS [CommonTable] WHERE [RecId] = @RowRecId FOR XML AUTO, BINARY BASE64 , ELEMENTS) --and then insert @RowData in 'CommonTable_History' table.
在“ sp_settriggerorder”的帮助下,我设置了这些触发器的执行顺序,因此首先执行“ Trigger1”,然后执行“ Trigger2”。
第二个触发器“ Trigger2”适用于插入/删除值。如果首次触发“ Trigger1”未更改新的插入值,则对新的插入值工作正常。
但是在某些情况下,“ Trigger1”中的插入值已更改。假设[StatusCode] =’新值’,而旧值是’旧值’,则“触发器2”仍存储“旧值”而不是“新值”。为什么因为“ Trigger1”更改了值,但是该值仍未存储在数据库中,并且在插入之前执行“ Trigger2”之前,为什么?现在我的要求是,在这里我要存储“新值”。
所以我想,让“ Trigger2”使用“ AFTER”关键字。但是“ FOR”和“ AFTER”的行为相同无法解决问题。
然后我想,让“ Trigger2”使用“ INSTEAD OF”关键字。但是“ INSTEAD OF”给出以下错误“无法创建INSTEAD OF DELETE或INSTEAD OF UPDATE TRIGGER。这是因为表具有带有级联DELETE或UPDATE的FOREIGN KEY。”
我无法使用表’CommonTable’的级联DELETE或UPDATE来删除FOREIGN KEY。
如果您还有其他替代解决方案,请告诉我。-维克拉姆·格洛特(Vikram Gehlot)
我认为您的第二个触发器需要使用实际表中的值,而不是插入/删除表中的值来填充日志表- 插入/删除将始终具有未更改的原始值,而更改后的值将显示在表中。将第二个触发器设为“ After”触发器,因此您不必使用sp_settriggerorder。像这样,例如:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[trg_Trig1] ON [dbo].[TestTable] FOR INSERT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; update TestTable set [value] = 10 where [value] = 25 END SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[trg_Trig2] ON [dbo].[TestTable] AFTER INSERT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for trigger here insert into log_TestTable (id, description, [value]) select tt.id, tt.description, tt.[value] from inserted i LEFT JOIN TestTable tt ON tt.id = i.id END