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

如何在SQL Server中捕获指定数据库未被捕获的错误至error_table

如何在SQL Server中捕获未处理错误并保存到error_table

嘿,我来帮你搞定这个需求!要在指定SQL Server数据库里自动捕获所有没被人工TRY/CATCH处理的错误,并存到error_table中,咱们分步骤来:

第一步:创建错误日志表

首先得先建个用来存错误信息的表,我给你列了几个实用的字段,能把关键的错误细节都记录下来:

CREATE TABLE error_table (
    error_id INT IDENTITY(1,1) PRIMARY KEY,
    error_number INT,
    error_message NVARCHAR(4000),
    error_severity INT,
    error_state INT,
    error_procedure NVARCHAR(128),
    error_line INT,
    database_name NVARCHAR(128),
    username NVARCHAR(128),
    error_datetime DATETIME DEFAULT GETDATE(),
    sql_statement NVARCHAR(MAX)
);

第二步:用扩展事件实现全局错误捕获

如果想不用修改现有代码,全局自动捕获所有未处理的错误,**扩展事件(Extended Events)**是最佳选择——这是SQL Server官方主推的轻量级监控方案,性能开销远低于老的SQL Trace,不会给数据库添额外负担。

创建扩展事件会话

执行下面的SQL,创建一个专门捕获未处理错误的会话:

CREATE EVENT SESSION [Capture_Unhandled_Errors] ON DATABASE 
ADD EVENT sqlserver.error_reported(
    ACTION(
        sqlserver.database_name,
        sqlserver.sql_text,
        sqlserver.username
    )
    WHERE (
        -- 过滤掉系统内部的错误,只抓用户会话产生的错误
        sqlserver.is_system = 0
        -- 只捕获没被TRY/CATCH处理的错误(is_handled=0就是未处理)
        AND is_handled = 0
    )
)
ADD TARGET package0.event_file(SET filename=N'Capture_Unhandled_Errors.xel'),
ADD TARGET package0.ring_buffer
WITH (STARTUP_STATE=ON); -- 确保SQL Server重启后这个会话自动启动,不用手动开

把扩展事件数据导入error_table

扩展事件会把错误数据写到.xel格式的文件里,你可以建个SQL Server代理定时作业,定期读取这些文件里的错误数据,插入到error_table中。给你个示例脚本:

DECLARE @file_path NVARCHAR(260) = N'Capture_Unhandled_Errors_*.xel';

INSERT INTO error_table (
    error_number,
    error_message,
    error_severity,
    error_state,
    error_procedure,
    error_line,
    database_name,
    username,
    sql_statement
)
SELECT
    XEventData.value('(event/data[@name="error_number"]/value)[1]', 'INT') AS error_number,
    XEventData.value('(event/data[@name="message"]/value)[1]', 'NVARCHAR(4000)') AS error_message,
    XEventData.value('(event/data[@name="severity"]/value)[1]', 'INT') AS error_severity,
    XEventData.value('(event/data[@name="state"]/value)[1]', 'INT') AS error_state,
    XEventData.value('(event/data[@name="procedure"]/value)[1]', 'NVARCHAR(128)') AS error_procedure,
    XEventData.value('(event/data[@name="line_number"]/value)[1]', 'INT') AS error_line,
    XEventData.value('(event/action[@name="database_name"]/value)[1]', 'NVARCHAR(128)') AS database_name,
    XEventData.value('(event/action[@name="username"]/value)[1]', 'NVARCHAR(128)') AS username,
    XEventData.value('(event/action[@name="sql_text"]/value)[1]', 'NVARCHAR(MAX)') AS sql_statement
FROM (
    SELECT CAST(event_data AS XML) AS XEventData
    FROM sys.fn_xe_file_target_read_file(@file_path, NULL, NULL, NULL)
) AS XEvents
WHERE
    -- 避免重复插入已经处理过的错误
    XEventData.value('(event/@timestamp)[1]', 'DATETIME') > ISNULL((SELECT MAX(error_datetime) FROM error_table), '1900-01-01');

启动扩展事件会话

最后,启动这个会话就开始捕获错误啦:

ALTER EVENT SESSION [Capture_Unhandled_Errors] ON DATABASE STATE = START;

备选方案:用TRY/CATCH包装存储过程

如果你的场景只需要覆盖存储过程里的错误,也可以用TRY/CATCH块配合统一的日志存储过程来实现——不过这个方法需要修改所有现有存储过程,适合小规模系统:

首先创建一个统一的错误日志存储过程:

CREATE PROCEDURE dbo.Log_Error
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO error_table (
        error_number,
        error_message,
        error_severity,
        error_state,
        error_procedure,
        error_line,
        database_name,
        username,
        sql_statement
    )
    VALUES (
        ERROR_NUMBER(),
        ERROR_MESSAGE(),
        ERROR_SEVERITY(),
        ERROR_STATE(),
        ERROR_PROCEDURE(),
        ERROR_LINE(),
        DB_NAME(),
        SUSER_SNAME(),
        (SELECT text FROM sys.dm_exec_sql_text(ERROR_PROCEDURE()))
    );
END;

然后在每个存储过程里加上TRY/CATCH:

CREATE PROCEDURE dbo.Your_Business_Procedure
AS
BEGIN
    BEGIN TRY
        -- 这里写你的业务逻辑代码
        SELECT 1/0; -- 模拟一个未处理的错误
    END TRY
    BEGIN CATCH
        -- 调用日志存储过程记录错误
        EXEC dbo.Log_Error;
        -- 可选:重新抛出错误,让上层调用方感知到错误
        THROW;
    END CATCH
END;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:36:54