我有一个专栏LastUpdate
在我数据库的所有表中,我想说“在插入更新时LastUpdate = getdate()
"
我可以使用触发器来做到这一点,但我发现很难为数据库的每个表编写数百个触发器。
- 如何动态创建影响所有表的触发器?
- 如何为每个表动态创建触发器?
更新任何表时都不可能触发触发器。
您可以动态生成所需的 SQL,如下所示:
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
);
为每个表生成 SQLLastUpdate
列沿着:
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
表返回到正在更新的表。
您可以复制并粘贴结果并执行它们(我推荐这种方式,这样您至少可以检查生成的 SQL,或者将其构建到游标中并使用sp_executesql
。我建议使用前者,即使用它来节省一些时间,但在实际创建触发器之前仍然检查每个触发器。
我个人认为最后修改的列是一个有缺陷的概念,对我来说,它总是感觉存储了令人烦恼的少量信息,如果您真的关心数据更改,那么可以使用审核表(或临时表,或使用更改跟踪)正确跟踪它们。首先,知道某些内容何时更改,但不知道更改的内容或更改者可能比根本不知道更烦人,其次它会覆盖所有以前的更改,是什么使最新的更改比所有已发生的更改更重要前。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)