【问题标题】:INSTEAD OF UPDATE triggers doing the standard update it was replacingINSTEAD OF UPDATE 触发器执行它正在替换的标准更新
【发布时间】:2015-03-03 10:02:53
【问题描述】:

这似乎是一个非常愚蠢的问题,但我在网上找不到任何信息如何做到这一点。

如果您正在设计一个将包装更新操作的触发器,那么您实际上是如何执行该操作的?我是否必须明确提及tbl_MyTable 中的每一列才能执行更新?对于未来潜在的模式更改,这似乎需要大量维护,而且我不想在启用递归时不必要地点击InsertDelete 触发器。

CREATE TRIGGER [dbo].[tr_MyUpdateTrigger]
ON [dbo].[tbl_MyTable]
INSTEAD OF UPDATE
AS
BEGIN
--Do the standard update operation on tbl_MyTable that this trigger is replacing
END

简而言之,如果不诉诸从已删除中删除和从插入中插入,或者明确提及表中的每一列,您如何才能完成更新。这甚至可能吗?

【问题讨论】:

    标签: sql-server triggers sql-server-2008-r2


    【解决方案1】:

    因为您使用的是 INSTEAD OF trigger,所以您必须进行更新 - 不能绕过它。如果您要使用 AFTER 触发器,那么您根本不需要执行 UPDATE。您应该使用哪种类型的触发器取决于您要达到的目标。

    只是为了澄清一件事,您不会从“已删除”伪表中删除并插入“已插入”伪表中。您在真实表上执行更新,并在适当的键上连接到“插入”伪表以获取新值。

    如果我不得不这样做,我可能会想用这样的东西来节省我打字的时间:)

    select N't.' + quotename(name) + N' = i.' + quotename(name) + N', ' as [--SQL] 
    from sys.columns 
    where object_id = object_id('dbo.MyTable') 
    order by column_id 
    

    不要忘记从生成的列表中删除 PK 列和任何其他不适当的列(即时间戳)。

    【讨论】:

    • 如果有人更新了主键,插入的将没有什么可加入的,因此我认为您必须根据已删除的 psudo 从真实表中删除,并根据插入的插入。但由于递归,我并不特别想这样做。
    • 好点!但是,我认为这更多地是一个设计问题——关于允许更新主键还有很多其他问题。您可以使用UPDATE()函数来测试主键列是否已更新并拒绝更新。
    • 嗯,对,所以我可以将 PK 的更新视为删除+插入,这确实有意义。对于不涉及 PK 更新的所有内容,只需根据插入的内容进行更新...这是否仍然涉及明确提及 tbl_MyTable 中的每一列?
    • @Izzy - 是的,每一列,虽然如果我不得不这样做,我可能会想使用类似select N't.' + quotename(name) + N' = i.' + quotename(name) + N', ' as [--SQL] from sys.columns where object_id = object_id('dbo.MyTable') order by column_id 的东西来节省我输入太多的时间:)
    • 诅咒!如果您将该提示编辑到您的答案中,我会接受。 :)
    猜你喜欢
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2012-04-30
    相关资源
    最近更新 更多