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

C#使用SqlCommand.ExecuteReader时如何捕获级别16的SQL抛出错误

你配置的conn.FireInfoMessageEventOnUserErrors = true会导致等级≤16的SQL用户错误不再以SqlException形式抛出,只会触发InfoMessage事件,因此你外层的catch块无法捕获到对应异常,可按以下两种方案解决:


方案1:直接通过catch捕获异常(推荐)

不需要配置InfoMessage相关属性,删除你添加的两行配置代码,直接捕获SqlException后判断错误等级即可,示例代码如下:

try
{
    using (SqlConnection conn = new SqlConnection(con))
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        conn.Open();
        string res = null;
        var reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            if (res == null) res = ""; 
            res += (reader[0] as string);
        }
        return res;
    }
}
catch (SqlException ex)
{
    // SqlException的Errors集合包含所有SQL返回的错误,Class属性对应错误级别
    foreach (SqlError err in ex.Errors)
    {
        if (err.Class == 16)
        {
            // 此处编写16级错误的自定义处理逻辑
        }
    }
    throw;
}
catch (Exception ex)
{
    // 其他非SQL异常处理逻辑
    throw;
}

方案2:保留InfoMessage事件处理

如果你确实需要通过InfoMessage事件处理所有SQL消息/错误,需要在事件回调方法中主动判断错误等级,如需触发外层catch则主动抛出异常:

事件回调方法示例

private void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    foreach (SqlError err in e.Errors)
    {
        if (err.Class == 16)
        {
            // 处理16级错误,如需中断流程抛出异常则添加以下代码
            throw new ApplicationException($"捕获到16级SQL错误:{err.Message}", e);
        }
    }
}

连接配置示例

conn.InfoMessage += conn_InfoMessage;
conn.FireInfoMessageEventOnUserErrors = true;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:06:02