【问题标题】:Feasibility of SQLCLR Trigger or Stored Procedure for Audit Trail?SQLCLR 触发器或审计跟踪存储过程的可行性?
【发布时间】:2011-12-29 15:43:25
【问题描述】:

免责声明:我无法在应用程序中正确实现这一点,因为我正在处理的应用程序没有以一致的方式进行数据访问,并且重构工作对于项目范围和即将到来的范围来说太大了截止日期。

我将如何为审计跟踪实现 SQLCLR 触发器?我希望它尽可能简单,并且在以后尽可能容易地删除和替换为适当的实现

我打算将我的审计写入单个表(数据库不是很重),具有如下列:

  • 时间戳 (datetime) - 更改发生的时间?
  • 用户名 (varchar) - 谁做了更改?
  • AffectedTableName (varchar) - 哪个表受到影响?
  • AffectedRowKey (varchar) - 这将是一个简单或复合键,例如 (Id=42, A=4,B=2)
  • OperationType (char(1)) - IUD 分别用于插入、更新和删除。
  • InsertedXml (xml) - xml 序列化行 (SELECT * FROM INSERTED FOR XML AUTO)
  • DeletedXml(xml) - xml 序列化行 (SELECT * FROM DELETED FOR XML AUTO)

我计划在应用程序中查询这些数据并将其解析为用户可读的表单。我打算将其实现为使用 SQLCLR 编写的数据库触发器。我可以看到 2 种可能的方法:

  • 将此完全实现为 SqlTrigger 方法:
  • 将此实现为带参数的 SqlProcedure 方法:
    • 架构名称
    • 表名
    • 插入的Xml
    • 已删除Xml

我将不胜感激任何建设性的批评和建议。我的限制是我必须使用触发器在数据库级别实现审计,并且我希望它尽可能可维护(阅读:可移动和可替换)。同样理想的是,我不希望数百个触发器具有完全相同的主体,以防我不得不修改它们。

【问题讨论】:

    标签: sql sql-server tsql triggers sqlclr


    【解决方案1】:

    SQLCLR 触发器中有一个严重的限制将阻止您在 SQLCLR 中实现审计触发器:您无法找到从 SQLCLR 触发器内部更改的父对象。即,如果您将单个 SQLCLR 触发器例程注册到多个表,则无法找到更新/插入/删除的表。乍一看,@@procID 可能看起来很有用,但是当从 SQLCLR 触发器内部调用时,@@procid 返回相同的值,无论哪个表受到影响。我已经搜索了互联网并进行了很多实验,但我没有找到解决方案。我发现更多人有同样的问题。有些消息可以追溯到 2006 年。

    我在 Microsoft Connect 上向 Microsoft 创建了功能请求。请登录并按向上箭头以实现它,以便您实际上可以使用 SQLCLR 触发器来实现您的目的:https://connect.microsoft.com/SQLServer/feedback/details/768358/a-sqlclr-trigger-should-be-given-the-parent-object-in-the-sqltriggercontext

    【讨论】:

      【解决方案2】:

      一段时间以来,我一直在使用此脚本的变体从我的一些项目中创建审计触发器,并取得了很好的效果:

      http://www.simple-talk.com/sql/database-administration/pop-rivetts-sql-server-faq-no.5-pop-on-the-audit-trail/

      【讨论】:

      • @sql 移到 while 循环之外,并将其替换为用于插入和删除的变量,然后在 while 循环之后只执行一次 @sql,使用您的插入和删除变量,如您的上面的架构。对不起,但我没有时间做这个小提示......祝你好运。
      猜你喜欢
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      相关资源
      最近更新 更多