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

如何在SQL Server存储过程中执行RAISERROR且让过程成功结束?

问题场景

现有SQL Server存储过程通过RAISERROR输出统计数量,以此触发日志系统写入日志文件供Hangfire监控使用。但RAISERROR会导致存储过程被标记为执行失败;用BEGIN TRY/BEGIN CATCH包裹后,日志记录又无法触发。需要实现RAISERROR正常触发日志,同时让存储过程成功结束。

原代码片段

IF EXISTS (SELECT 1 FROM @UnprocessedCollaterals)
BEGIN
    DECLARE @ErrorMessage NVARCHAR(MAX);
    
    DECLARE @Count int;
    SELECT @Count = COUNT(DISTINCT CollUpdProcessPK)
    FROM @Unprocessed;

    RAISERROR ('Total: %d', 16, 1, @Count);

END;

尝试的代码

BEGIN TRY
    RAISERROR ('Total: %d', 16, 1, @Count);
END TRY
BEGIN CATCH

END CATCH

解决方案

核心思路是调整错误消息的触发逻辑,既要让日志系统捕获到信息,又不触发存储过程的失败标记。

方法1:降低RAISERROR的错误级别

SQL Server中,错误级别1-10属于信息性消息,不会触发异常、不会标记存储过程失败,但仍会输出消息。如果日志系统能捕获这类信息,直接修改级别即可:

IF EXISTS (SELECT 1 FROM @UnprocessedCollaterals)
BEGIN
    DECLARE @Count int;
    SELECT @Count = COUNT(DISTINCT CollUpdProcessPK)
    FROM @Unprocessed;

    -- 将错误级别从16改为10(信息级别),加NOWAIT确保消息即时输出
    RAISERROR ('Total: %d', 10, 1, @Count) WITH NOWAIT;
END;

方法2:捕获异常后重新输出消息(针对必须用级别16的场景)

如果日志系统只能捕获级别≥16的错误,可在CATCH块中重新输出消息,避免存储过程因异常终止:

IF EXISTS (SELECT 1 FROM @UnprocessedCollaterals)
BEGIN
    DECLARE @Count int;
    SELECT @Count = COUNT(DISTINCT CollUpdProcessPK)
    FROM @Unprocessed;

    BEGIN TRY
        RAISERROR ('Total: %d', 16, 1, @Count);
    END TRY
    BEGIN CATCH
        -- 用PRINT输出错误信息,或用低级别RAISERROR保持格式
        PRINT ERROR_MESSAGE();
        -- 可选:RAISERROR(ERROR_MESSAGE(), 10, 1) WITH NOWAIT;
    END CATCH
END;

方法3:用THROW配合TRY/CATCH(SQL Server 2012+)

如果使用SQL Server 2012及以上版本,用THROW抛出自定义错误,再在CATCH中处理,既能触发日志又能让存储过程正常结束:

IF EXISTS (SELECT 1 FROM @UnprocessedCollaterals)
BEGIN
    DECLARE @Count int;
    SELECT @Count = COUNT(DISTINCT CollUpdProcessPK)
    FROM @Unprocessed;
    DECLARE @Msg NVARCHAR(MAX) = FORMATMESSAGE('Total: %d', @Count);

    BEGIN TRY
        -- 自定义错误号(需在50000-2147483647范围内)
        THROW 50000, @Msg, 1;
    END TRY
    BEGIN CATCH
        PRINT ERROR_MESSAGE();
        -- 可选:RAISERROR(ERROR_MESSAGE(), 10, 1) WITH NOWAIT;
    END CATCH
END;

内容的提问来源于stack exchange,提问作者B. Baxter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 05:38:13