【问题标题】:Track changes (update, insert) in database跟踪数据库中的更改(更新、插入)
【发布时间】:2021-07-11 07:03:56
【问题描述】:

我管理的 Web 应用程序在很多方面都很糟糕,而且没有很好的文档记录。由于我从一开始就没有参与过这个项目,所以我需要更好地了解自己。我正在使用本地机器进行测试,性能不是什么大问题,所以如果解决方案很慢 - 也没关系。

我想看看当我在应用程序中使用某些功能时,数据库中发生了哪些更改以及哪些表受到影响(MS SQL Server 2012)。我已经阅读了有关审计功能、变更跟踪和变更数据捕获的信息。也许我不完全理解这些,或者我需要一些不同的东西。有什么建议吗?

这是我想要的(跟踪哪些表数据被更改)甚至可能实现吗?

到目前为止,我在我的数据库副本中添加了一个审计表 (AAA_Audit2),并启动了一个触发器,当对我的用户表执行插入操作时,该触发器会更新该表。

AUDIT 表如下所示:

ID | table_name | command | time_stamp

在写这篇文章时,我想出了一个想法(来自one trigger for all tables 的帮助)并得到了一些代码来展示。

由于我需要为很多表部署此触发器,因此我编写了一个如下所示的触发器:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

SELECT 'CREATE TRIGGER' + QUOTENAME('trgTraceDMLin' + name) + 'ON' + QUOTENAME(name)
 + 'FOR INSERT, UPDATE, DELETE AS 

BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    
    INSERT INTO [dbo].[AAA_AUDIT2] (ID, table_name, command, time_stamp)

    VALUES (
    QUOTENAME(name),
    [INSERT],
    GETDATE() );
    GO'

FROM dbo.sysobjects
WHERE xtype = 'U'

END
GO

现在我在 Management Studio 中收到一条错误消息,提示“期待对话”。那是什么意思?谷歌搜索让我更加困惑。

感谢您阅读本文!

【问题讨论】:

  • 你能发布确切的完整错误吗?
  • 你有一个任性的END。我假设 END 应该在您的动态语句中,而不是在它之外。 GOnot 是一个 T-SQL 操作符,它是一个 IDE 操作符;会导致动态语句出错。
  • “END”附近的语法不正确。同样在最后一个 GO-'GO' 附近的语法不正确。期待对话。
  • @larnu - 成功了。看起来它现在正在工作。
  • 第一行也缺少一些空格,只是因为QUOTENAME[] 放在名称周围而导致错误

标签: sql-server tsql triggers audit change-tracking


【解决方案1】:

抱歉回复晚了。我只是想提供一个更新,也许其他人会从中得到一些帮助。

为所有表生成触发器的查询,可能您需要一个不同的触发器来进行插入、更新和删除:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

SELECT 'CREATE TRIGGER ' + QUOTENAME('trgTraceDMLin' + name) + ' ON ' + QUOTENAME(name) + ' FOR INSERT, UPDATE, DELETE AS 

BEGIN

    SET NOCOUNT ON;

    INSERT INTO [dbo].[AAA_AUDIT] (table_name, command, time_stamp)

    VALUES (' + CHAR(39) +
    QUOTENAME(name) + CHAR(39) + ',
    ''INSERT'',
    GETDATE() );


    END'

FROM dbo.sysobjects
WHERE xtype = 'U'

查询给出一个可以复制和执行的结果,这将最终在所有表上生成触发器。

此解决方案不适用于我管理的应用程序,因为我立即遇到了几个死锁。

我改变了焦点并在所有表上激活了 CDC(更改数据捕获),只是为了在那些写入我的审计表的 CDC 表上放置一个触发器。它正在工作......不知何故。但我想我会让你知道的。

查询以在所有表​​上启用 CDC:

DECLARE @TableName VARCHAR(100)

DECLARE @TableSchema VARCHAR(100)

DECLARE CDC_Cursor CURSOR FOR
  SELECT *
  FROM   (
         
       --  SELECT 'T' AS TableName,'dbo' AS TableSchema
         -- UNION ALL
          --SELECT 'T2' AS TableName,'dbo' AS TableSchema
           --IF want to Enable CDC on All Table, then use
         SELECT Name,SCHEMA_NAME(schema_id) AS TableSchema
         FROM   sys.objects
         WHERE  type = 'u'
                AND is_ms_shipped <> 1
         ) CDC

OPEN CDC_Cursor

FETCH NEXT FROM CDC_Cursor INTO @TableName,@TableSchema

WHILE @@FETCH_STATUS = 0
  BEGIN
      DECLARE @SQL NVARCHAR(1000)
      DECLARE @CDC_Status TINYINT

      SET @CDC_Status=(SELECT COUNT(*)
          FROM   cdc.change_tables
          WHERE  Source_object_id = OBJECT_ID(@TableSchema+'.'+@TableName))

      --IF CDC Already Enabled on Table , Print Message
      IF @CDC_Status = 1
        PRINT 'CDC is already enabled on ' +@TableSchema+'.'+@TableName
              + ' Table'

      --IF CDC is not enabled on Table, Enable CDC and Print Message
      IF @CDC_Status <> 1
        BEGIN
            SET @SQL='EXEC sys.sp_cdc_enable_table
      @source_schema = '''+@TableSchema+''',
      @source_name   = ''' + @TableName
                     + ''',
      @role_name     = null;'

            EXEC sp_executesql @SQL

            PRINT 'CDC  enabled on ' +@TableSchema+'.'+ @TableName
                  + ' Table successfully'
        END

      FETCH NEXT FROM CDC_Cursor INTO @TableName,@TableSchema
  END

CLOSE CDC_Cursor

DEALLOCATE CDC_Cursor 

感谢您的意见!

T

【讨论】:

    猜你喜欢
    • 2010-09-24
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2011-09-30
    • 2021-05-16
    • 2016-05-10
    相关资源
    最近更新 更多