我的LastUpdate数据库的所有表中都有一列,我想说“在插入更新时LastUpdate = getdate()”
LastUpdate
LastUpdate = getdate()
我可以使用触发器来做到这一点,但是我发现很难为数据库的每个表编写数百个触发器。-如何动态创建影响所有表的触发器?-如何为每个表动态创建触发器?
更新任何表时都无法触发触发器。
您可以动态生成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 );
为每个表生成带有LastUpdate一行的列的SQL :
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
依赖于每个具有主键的inserted表,以使表中的联接返回到要更新的表。
inserted
您可以复制并粘贴结果并执行它们(我建议这样做,这样您至少可以检查生成的SQL,或将其构建到游标中并使用来执行sp_executesql。我建议使用前者,即,使用它来保存有点时间,但是在实际创建触发器之前,仍然要检查每个触发器。
sp_executesql
我个人认为最后修改的列是一个有缺陷的概念,在我看来,它总是像存储烦人的信息一样,如果您真的关心数据更改,然后使用审核表对其进行适当跟踪。首先,知道什么时候改变了,但是改变了什么,或者是谁改变了,这比根本不知道更令人讨厌,其次,它覆盖了以前的所有改变,是什么使最新的改变比以前的所有改变更重要。