【问题标题】:Use one SQL Server trigger that listens on updates of multiple tables使用一个 SQL Server 触发器来侦听多个表的更新
【发布时间】:2016-08-11 21:39:15
【问题描述】:

我有一个包含多个表的 Microsoft SQL Server 2012 数据库。

所有表都包含相同的两列DataRowModified(类型datetime)和DataRowLastAuthor(类型nvarchar(MAX))。不,我不能将所有这些列放到一个单独的表中,要求每个表都直接包含这些行。

我为表Events 编写了下面的触发器,以便在更新行时自动更新这两列的值:

CREATE TRIGGER [dbo].[Trigger_Events_UpdateMetadata]
    ON [dbo].[Events]
    FOR UPDATE
    AS
    BEGIN
        UPDATE [dbo].[Events] 
        SET [DataRowModified] = GETDATE(),
            [DataRowLastAuthor] = ORIGINAL_LOGIN()
        WHERE [Id] IN (SELECT [Id] FROM INSERTED)
    END

现在我的问题是我是否必须为我必须使用的每个表复制(并重命名)这个触发器,或者我可以以某种方式编写一个适用于所有(或一组指定)表的全局触发器?它必须知道更新发生在哪个表/行中,因为它必须修改它。

如前所述,将自动维护的 LastAuthorLastModificationDate 列实现到多个表中的最简单方法是什么?

【问题讨论】:

  • 这里的触发器有几个问题。 marc_s 已经讨论了您要使用的概念,因此我将仅在此处提及触发器的内容。首先,当您只需要一个时,您正在使用两个更新语句。其次,可能是一个更大的问题,是您没有在代码中使用插入的表。正如发布的那样,这将更新事件表中的每一行,我非常怀疑这是你想要的。在 EXECUTE AS 的情况下,您可能还应该使用 ORIGINAL_LOGIN 而不是 SUSER_NAME。
  • @SeanLange 感谢您的评论,我对 SQL 还是很陌生。您如何看待我在问题中编辑的更新触发代码?
  • 我会推翻这个要求——要么这两列毫无意义,要么你会发现你实际上需要一个完整的审计跟踪。否则,考虑由两个用户执行的两次更新。用户 A 执行具有实际财务后果的破坏性更新。用户 B 执行简单的拼写更正。你的表告诉你什么?只有那个用户 B 是最后一个执行某种更新的人。
  • @Damien_The_Unbeliever 该项目并不那么重要,它只是一个可以管理事件并从中创建传单和其他文档的程序。我也有这个作为实习项目,我提到的日志列是老板要求的。但如果我没有这些限制,我会完全同意你的观点。

标签: sql-server triggers


【解决方案1】:

SQL Server 中的触发器始终绑定到单个表 - 您不能将“全局”触发器或触发器同时附加到多个表。

如果您需要在 50 个表上使用触发器 - 您需要编写 50 个触发器,每个表一个。没有办法解决这个问题。

避免这种情况的唯一方法是更新应用程序数据库层中的这些列,以便在保存数据行时这些值已经存在。实体框架之类的东西允许对多个实体进行此类“批量操作”,例如更新上次修改日期和上次修改实体的用户。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多