确定删除表中所有行的操作

时间:2014-10-03 08:31:25

标签: sql sql-server triggers sql-server-2012 audit

有三个不同的应用程序使用的SQL Server 2012数据库。在该数据库中有一个包含~500k行的表,出于某种神秘的原因,该表不时被清空。我认为这可能是由以下原因造成的:

  • 没有where子句的删除查询
  • 循环中的删除查询

我试图通过查看代码找到问题的原因,但没有快乐。我需要一个替代策略。我认为我可以使用触发器来检测所有行被删除的原因/原因,但我不知道如何解决这个问题。所以:

  • 我可以使用触发器来检查查询是否正在尝试删除所有行吗?
  • 我可以使用触发器记录有问题的查询以及发出该查询的应用吗?
  • 我可以使用触发器将此类操作记录到文本文件/数据库表/电子邮件中吗?
  • 有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用扩展事件来监控您的系统。 这里有一个简单的屏幕截图。

Extended Events

一个简单的政策可以监控删除截断语句。 引发此事件时,详细信息将写入文件。

这里有一个屏幕,其中包含为删除语句收集的详细信息(您可以配置脚本以收集更多数据)。

List Events

这里使用的脚本,修改输出文件路径

CREATE EVENT SESSION [CheckDelete] ON SERVER 
ADD EVENT sqlserver.sql_statement_completed(SET collect_statement=(1)
    ACTION(sqlserver.client_connection_id,sqlserver.client_hostname)
    WHERE ([sqlserver].[like_i_sql_unicode_string]([statement],N'%delete%') OR [sqlserver].[like_i_sql_unicode_string]([statement],N'%truncate%'))) 
ADD TARGET package0.event_file(SET filename=N'C:\temp\CheckDelete.xel',max_file_size=(50))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

答案 1 :(得分:0)

这可能对您有所帮助。它会在Table1上创建一个触发器,当进程DELETE超过100条记录时,该触发器会发送一封电子邮件。我修改消息以包含一些有用的数据,如:

  1. 进程ID(@@SPID
  2. 主持人(HOST_NAME()
  3. 应用名称(APP_NAME()
  4. 可能是整个查询

  5. CREATE TRIGGER Table1MassDeleteTrigger
    ON dbo.Activities
    FOR DELETE 
    AS
        DECLARE @DeleteCount INT = (SELECT COUNT(*) FROM deleted)
    
        IF(@DeleteCount > 100)
            EXEC msdb.dbo.sp_send_dbmail
            @profile_name = 'MailProfileName',
            @recipients = 'admin@yourcompany.com',
            @body = 'Something is deleting all your data!',
            @subject = 'Oops!';