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
相关产品推荐
相关产品推荐

