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

2023-11-25

我有一个专栏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(使用前将#替换为@)

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

随机推荐

  • 参考:使用 MySQL 扩展的完美代码示例是什么? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 这是为了创建一个社区学习资源 我们的目标是提供良好的代码示例 这些代码不会重复复制 粘贴
  • Java继承

    因此 我一直在尝试找到正确的方法来让应该非常简单的继承发挥作用 按照我想要的方式 但我惨败了 考虑一下 class Parent public String name Parent public Parent public void doS
  • ASP.Net Identity 和 IdentityServer4 声明

    我使用 IdentityServer4 作为 OIDC 提供程序和 ASP NET Core 2 0 我已经阅读了几篇文章 以确保 IdentityServer 发出的声明最终出现在 ClaimsPrincipal 即 Auth Cooki
  • 如何查找数组中出现次数最多的项目[重复]

    这个问题在这里已经有答案了 如何找到数组中出现次数最多的项 1 1 1 2 3 mode gt 1 cat dog snake dog mode gt dog 首先构建一个哈希 将数组中的每个值映射到其频率 arr 1 1 1 2 3 fr
  • PyDev 和 Eclipse 未解决的导入问题

    尽管我已经多次使用 Eclipse for Java 但我对 PyDev 和 Python 还很陌生 我正在尝试解决一些 Dive Into Python 示例 这感觉像是一个极其微不足道的问题 但现在却变得非常烦人 我使用的是 Ubunt
  • 使用 method_add 动态覆盖实例方法了解 ruby​​ 元编程

    我有以下来自 Programming Ruby 1 9 的代码 稍作修改 我只是想确保我的思维过程是准确的 module Trace def self included culprit Inject existing methods wit
  • (276/304)*304 的小数舍入关闭

    如果将以下代码放入编译器中 结果会有点奇怪 decimal x 276 304 304 double y 276 304 304 Console WriteLine decimal x x Console WriteLine double
  • Apache 应该服务什么,Tomcat 应该服务什么?

    我正在尝试在 Tomcat 之前设置 Apache Apache 提供什么服务 我知道 Apache 对于静态页面和图像效果更好 我目前在 Tomcat 中部署了一个 war 文件 其中包含静态页面 图像和 Flash 文件 我应该把这些都
  • ASP.NET 托管环境/shadowCopyBinAssemblies

    今天我偶然发现了ShadowCopyBinAssemblies选项中的托管环境 tag 显然这个属性是网络配置 system web 配置布尔选项 指示 Bin 目录中应用程序的程序集是否卷影复制到应用程序的 ASP NET 临时文件目录
  • 未添加本机代码的 Java 致命错误 SIGSEGV

    我从 Java 编译器收到一条我不理解的错误消息 我已经使用 Java 6 和 7 在 OSX 10 6 10 9 和 Ubuntu 14 04 上测试了我的代码 当我使用 Eclipse 调试器或解释器 使用 Xint 选项 运行时 一切
  • Django 无法迁移 PostgreSQL:关系 Y 的约束 X 不存在

    我正在尝试在 PostgreSQL 9 6 5 数据库上运行 Django 1 11 迁移 但出现了奇怪的错误 Applying myapp 0011 auto 20171130 1807 Traceback most recent cal
  • sqlalchemy中的连接池是线程安全的吗?

    文档称连接池也不是为多线程设计的 至关重要的是 当使用连接池时 以及扩展时 使用通过 create engine 创建的引擎 连接不会与分叉进程共享 TCP 连接是 表示为文件描述符 通常跨进程工作 边界 这意味着这将导致对文件的并发访问
  • iPhone 应用程序无法在旧设备(3G、3GS...)上运行[重复]

    这个问题在这里已经有答案了 可能的重复 使用 Xcode 4 2 和 iOS 5 SDK 时是否可以针对旧版 iOS 版本 我开发了一个适用于 iPhone 4 iOS 4 3 和 5 的应用程序 在开发过程中使用 现在我尝试在3GS iO
  • 您可以记录角度数据绑定错误吗?

    如果绑定属性或表达式失败 是否有办法记录 i e
  • 如何为 JBoss 实例设置代理

    我有一个正在运行的 JBoss 实例 我想通过代理路由所有流量 我尝试将系统属性设置为在 run sh 中加载 如下所示 JAVA OPTS Dhttp proxyHost localhost Dhttp proxyPort 1234 JA
  • 发送电子邮件而无需在 Google 中启用不太安全的应用程序

    我用 C 制作了一个电子邮件程序 但您必须在 google 中启用不太安全的应用程序 有没有解决的办法 如果不是 其他应用程序如何安全地发送电子邮件而不被归类为安全性较低的应用程序 private void SendButton Click
  • 聚合物多重继承/组合

    高分子网站says在 Polymer 中使用 extend 属性不支持多重继承 或组合 我希望一个元素由一个 Polymer 元素中的一些方法和另一个 Polymer 元素中的一些方法组成 以使其反映应用程序逻辑 目前有什么方法可以在 Po
  • 正则表达式替换除破折号之外的非单词

    我有一个正则表达式模式 W 不适合h e l l o w o r d 替换字符串为 它返回类似这样的内容 h w 我希望至少能看到这样的事情 h e l l o w o r d 如何替换所有非单词字符和 不包括 symbol 要匹配除破折号
  • 为什么 strtotime 在不同时区给出不同的结果?

    我不知道为什么strtotime 在 PHP 中 即使给出相同的日期作为参数 在不同的时区也会返回不同的结果 有人知道答案吗 我也想知道 我可以做类似的任务 转换datetime to an int轻松地进行计算 与另一个在不同时区给出相同
  • 如何为 SQL Server 数据库中的所有表创建触发器

    我有一个专栏LastUpdate在我数据库的所有表中 我想说 在插入更新时LastUpdate getdate 我可以使用触发器来做到这一点 但我发现很难为数据库的每个表编写数百个触发器 如何动态创建影响所有表的触发器 如何为每个表动态创建