You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSSMS 2012用户取消操作无法触发TRY CATCH捕获求助

问题描述

在MSSMS 2012中执行SQL脚本时,若用户手动取消操作,原本用于记录错误事件的TRY CATCH块并未触发,自定义日志表的更新语句从未执行,预期写入的错误号45188和错误文本"The operation has been cancelled by user."均为NULL。

当前使用的代码如下:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


SET NOCOUNT ON;
SET XACT_ABORT ON;
SET ANSI_WARNINGS OFF

BEGIN TRY
    
    --INSERT FOR LOGGING THE TRANSACTION

    BEGIN TRANSACTION

    --CODE CANCELLED BY USER

    --UPDATE FOR LOGGING THE TRANSACTION'S SUCCESS

    COMMIT TRANSACTION

END TRY 
BEGIN CATCH
    DECLARE
    @V_ERROR_NUM INT = ERROR_NUMBER(),
    @V_ERROR_MSG VARCHAR(1000)=ERROR_MESSAGE(), 
    @V_ERROR_SEVERITY VARCHAR(100)=ERROR_SEVERITY(), 
    @V_ERROR_STATE VARCHAR(10)=ERROR_STATE()


    --UPDATE FOR LOGGING THE TRANSACTION'S ERROR


    RAISERROR(@V_ERROR_MSG,@V_ERROR_SEVERITY,@V_ERROR_STATE);
END CATCH

SET ANSI_WARNINGS ON
原因分析

用户手动取消操作(如SSMS中点击「取消执行」)属于批处理终止事件,SQL Server会直接中断当前批处理的所有执行流程,TRY/CATCH块无法捕获这类事件——因为批处理被强制终止后,CATCH块的代码根本没有机会执行。

解决方案

1. 使用扩展事件捕获取消操作

这是SQL层最可靠的记录方式,通过创建扩展会话捕获sqlserver.cancel_session事件,将取消操作的信息持久化到目标存储:

-- 创建扩展会话
CREATE EVENT SESSION [CaptureUserCancels] ON SERVER 
ADD EVENT sqlserver.cancel_session(
    ACTION(sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
)
ADD TARGET package0.event_file(SET filename=N'C:\SQLLogs\UserCancels.xel')
WITH (STARTUP_STATE=OFF)
GO

-- 启动会话
ALTER EVENT SESSION [CaptureUserCancels] ON SERVER STATE = START;
GO

后续可以读取事件文件中的数据,或者配置目标为自定义表来直接记录到日志表中。

2. 应用层补充控制

如果是通过应用程序调用SQL脚本,可以在应用层捕获用户取消的信号(比如.NET中的SqlCommand.Cancel()事件),然后主动调用日志插入语句,确保取消操作被记录。

3. 代码层面的优化(仅针对常规错误)

当前代码中的SET XACT_ABORT ON仅能处理常规执行错误,无法影响用户取消这类强制终止事件。若要确保常规错误被捕获,现有TRY/CATCH逻辑是有效的,但对用户取消场景不适用。

内容的提问来源于stack exchange,提问作者RindoquesUwU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:42:18