如何为SQL Server数据库中的所有表创建触发器

Bel*_*ash 1 sql t-sql triggers

我的LastUpdate数据库的所有表中都有一列,我想说"插入更新LastUpdate = getdate()"

我可以使用触发器执行此操作,但我发现很难为数据库的每个表写入数百个触发器. - 如何动态创建影响所有表的触发器? - 如何为每个表动态创建触发器?

Gar*_*thD 8

更新任何表时,无法触发触发器.

您可以动态生成SQL Required,如下所示:

SELECT  N'
            CREATE TRIGGER trg_' + t.Name + '_Update ON ' + ObjectName + '
            AFTER UPDATE 
            AS 
            BEGIN
                UPDATE  t
                SET LastUpdate = GETDATE()
                FROM ' + o.ObjectName + ' AS t
                        INNER JOIN inserted AS i
                            ON ' + 
            STUFF((SELECT ' AND t.' + QUOTENAME(c.Name) + ' = i.' + QUOTENAME(c.Name)
                    FROM    sys.index_columns AS ic
                            INNER JOIN sys.columns AS c
                                ON c.object_id = ic.object_id
                                AND c.column_id = ic.column_id
                    WHERE   ic.object_id = t.object_id
                    AND     ic.index_id = ix.index_id
                    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 4, '') + ';
            END;
            GO'
FROM    sys.tables AS t
        INNER JOIN sys.indexes AS ix
            ON ix.object_id = t.object_id
            AND ix.is_primary_key = 1
        CROSS APPLY (SELECT QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + '.' + QUOTENAME(t.name)) o (ObjectName)
WHERE   EXISTS 
        (   SELECT  1 
            FROM    sys.columns AS c 
            WHERE   c.Name = 'LastUpdate' 
            AND     c.object_id = t.object_id
        );
Run Code Online (Sandbox Code Playgroud)

为每个表生成SQL,其中包含LastUpdate以下行的列:

CREATE TRIGGER trg_TableName_Update ON [dbo].[TableName]
AFTER UPDATE 
AS 
BEGIN
    UPDATE  t
    SET     LastUpdate = GETDATE()
    FROM    [dbo].[TableName] AS t
            INNER JOIN inserted AS i
                ON  t.[PrimaryKey] = i.[PrimaryKey];
END;
GO
Run Code Online (Sandbox Code Playgroud)

依赖于具有主键的每个表来从inserted表返回到正在更新的表的连接.

您可以复制并粘贴结果并执行它们(我建议这样做,这样您至少可以检查SQL Generated,或者将其构建到游标中并使用它来执行sp_executesql.我会推荐前者,即使用它来保存一点时间,但在实际创建之前仍然检查每个触发器.

我个人认为最后修改过的列是一个有缺陷的概念,我总觉得存储烦人的小信息,如果你真的关心数据变化,那么用审计表正确地跟踪它们.首先,知道什么时候发生了变化,但改变了什么,或者改变了什么可能比不知道更烦人,其次它覆盖了之前的所有变化,是什么让最新的变化比之前的变化更重要.

  • 没问题.如果这解决了您的问题,请将其标记为[已接受的答案](http://meta.stackexchange.com/q/5234),以便向其他人表明您的问题已解决且无需提交新答案,或者这个方法帮助你的同样问题的其他人.您可能还希望查看其他一些问题,截至48个问题中,只有3个问题已被接受.如果只有3个答案有帮助,那么这很好,但如果他们已经解决了你的问题,那么你应该将它们标记为答案. (2认同)