如何配置SQL Server日志以捕获数据库删除操作详情?
问题背景
我正在开发一个用于清理数据库对象的DLL,该DLL依赖于一个可执行文件。执行删除ID为140043的对象操作时,发现同类型的ID为140047的对象也被一并删除。我怀疑是应用程序逻辑导致,但暂时无法直接定位原因,打算通过分析SQL Server日志来确认具体执行的删除语句类型:
- 是连续执行两条独立的
delete Order where Id=140043和delete Order where Id=140047语句 - 还是执行了类似
delete Order where Id in (Select whatever from other_table where Id=140043)的关联删除查询
目前SQL Server日志并未记录这些删除操作,需要了解如何配置实例以记录所有此类操作。另外,我的数据库是通过Telerik框架的源代码进行配置的,希望能在代码中完成日志相关配置。
删除操作的典型代码如下:
database.RemoveObject(current_obj); database.SaveChanges(); // 完成ID140043的删除后,另一个对象也被删除
代码结构示例:
namespace <Firm>.<Customer>.Server.OpenAccess { [Export(typeof(MetadataSource))] class DataMetadataSource : FluentMetadataSource { ... } }
解决方案
一、配置SQL Server记录所有删除操作
方法1:使用SQL Server Profiler(临时排查首选)
- 打开SQL Server Profiler,新建跟踪并连接目标实例
- 在「事件选择」中勾选以下事件:
- SQL:BatchCompleted(捕获批量SQL执行完成事件)
- RPC:Completed(捕获存储过程或远程调用完成事件)
- 在「列筛选器」中,对TextData列设置筛选规则:包含
delete关键词,仅保留删除操作相关日志 - 启动跟踪后执行删除操作,即可查看捕获到的具体SQL语句
方法2:开启扩展事件(长期监控首选,性能影响小)
执行以下SQL脚本创建并启动扩展事件会话:
-- 创建会话 CREATE EVENT SESSION [CaptureDeleteStatements] ON SERVER ADD EVENT sqlserver.sql_statement_completed( WHERE ([sqlserver].[like_i_sql_unicode_string]([statement],N'%delete%'))) ADD TARGET package0.event_file(SET filename=N'CaptureDeleteStatements.xel',max_file_size=(5),max_rollover_files=(2)) WITH (STARTUP_STATE=OFF) -- 启动会话 ALTER EVENT SESSION [CaptureDeleteStatements] ON SERVER STATE = START
查看日志:在SSMS的「管理->扩展事件->会话」中找到该会话,右键选择「查看目标数据」即可查看捕获到的删除语句。
方法3:利用事务日志记录(需注意日志体积)
- 将数据库恢复模式设置为完整恢复模式:
ALTER DATABASE [YourDatabaseName] SET RECOVERY FULL;
- 使用
fn_dblog系统函数解析事务日志,或借助日志分析工具读取删除操作记录,此方法适合需要追溯历史操作的场景。
二、在Telerik OpenAccess代码中配置SQL日志
在DataMetadataSource类中重写ConfigureBackend方法,直接开启SQL语句日志记录,无需依赖SQL Server实例配置:
namespace <Firm>.<Customer>.Server.OpenAccess { [Export(typeof(MetadataSource))] class DataMetadataSource : FluentMetadataSource { protected override BackendConfiguration ConfigureBackend() { var backendConfig = base.ConfigureBackend(); // 开启SQL日志记录 backendConfig.LoggingOptions.LogLevel = LogLevel.Info; backendConfig.LoggingOptions.LogCategory = LogCategory.Sql; // 配置日志输出目标:控制台 backendConfig.LoggingOptions.AddListener(new ConsoleTraceListener()); // 可选:输出到文件 // backendConfig.LoggingOptions.AddListener(new TextWriterTraceListener("openaccess_sql.log")); return backendConfig; } // 原有配置代码... } }
配置完成后,执行SaveChanges()时生成的所有SQL语句(包括删除操作)都会被输出到指定目标,直接从日志即可确认执行的语句类型。
内容的提问来源于stack exchange,提问作者Dominique
相关产品推荐
相关产品推荐

