【发布时间】: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
现在我的问题是我是否必须为我必须使用的每个表复制(并重命名)这个触发器,或者我可以以某种方式编写一个适用于所有(或一组指定)表的全局触发器?它必须知道更新发生在哪个表/行中,因为它必须修改它。
如前所述,将自动维护的 LastAuthor 和 LastModificationDate 列实现到多个表中的最简单方法是什么?
【问题讨论】:
-
这里的触发器有几个问题。 marc_s 已经讨论了您要使用的概念,因此我将仅在此处提及触发器的内容。首先,当您只需要一个时,您正在使用两个更新语句。其次,可能是一个更大的问题,是您没有在代码中使用插入的表。正如发布的那样,这将更新事件表中的每一行,我非常怀疑这是你想要的。在 EXECUTE AS 的情况下,您可能还应该使用 ORIGINAL_LOGIN 而不是 SUSER_NAME。
-
@SeanLange 感谢您的评论,我对 SQL 还是很陌生。您如何看待我在问题中编辑的更新触发代码?
-
我会推翻这个要求——要么这两列毫无意义,要么你会发现你实际上需要一个完整的审计跟踪。否则,考虑由两个用户执行的两次更新。用户 A 执行具有实际财务后果的破坏性更新。用户 B 执行简单的拼写更正。你的表告诉你什么?只有那个用户 B 是最后一个执行某种更新的人。
-
@Damien_The_Unbeliever 该项目并不那么重要,它只是一个可以管理事件并从中创建传单和其他文档的程序。我也有这个作为实习项目,我提到的日志列是老板要求的。但如果我没有这些限制,我会完全同意你的观点。
标签: sql-server triggers