【发布时间】:2017-07-24 21:52:20
【问题描述】:
我试图找到这个问题的有用答案,但失败了(我找到的最接近的是this)。我有一个 C# 应用程序调用一个存储过程,它使用 SQL TRY/CATCH 来处理错误。我可以使用这样的示例存储过程来复制该问题:
if object_id('dbo.TestSQLError') is not null drop proc dbo.TestSQLError
go
create proc dbo.TestSQLError
as
begin try
select 1 / 0
end try
begin catch
raiserror('Bad tings appen mon', 16, 1)
end catch
然后是一个像这样的小程序:
namespace TestSQLError
{
class Program
{
public const string CONNECTION_STRING = @"data source=localhost\koala; initial catalog=test; integrated security=true;";
static void Main(string[] args)
{
try
{
using (SqlConnection conn = new SqlConnection(CONNECTION_STRING))
{
SqlCommand cmd = new SqlCommand("dbo.TestSQLError", conn) { CommandType = System.Data.CommandType.StoredProcedure };
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr.GetValue(0).ToString());
}
rdr.Close();
}
conn.Close();
}
Console.WriteLine("Everything looks good...");
}
catch (SqlException se)
{
Console.WriteLine("SQL Error: " + se.Message);
throw se;
}
catch (Exception e)
{
Console.WriteLine("Normal Error: " + e.Message);
throw e;
}
Console.ReadLine();
}
}
}
存储过程引发了 16 级错误,据我所知,这应该足以引起错误。然而,控制永远不会跳转到 catch 块;它只是突如其来,就像什么都没出错一样。
我读到有人建议使用OUTPUT 参数...我可以这样做,但似乎我必须在这里遗漏一些基本和简单的东西。有人可以帮忙吗?
更新:如果我使用 ExecuteNonQuery() 会出现错误传播得很好。但是,我的用例是一个执行 DML 并基于该 DML 返回数据的过程。也许答案是“不要那样做”,但很高兴知道是否有办法在获取结果时简单地捕获错误。
【问题讨论】:
-
尝试在
RAISERROR之后立即添加RETURN语句 -
它在 TDS 流中的读取可能不如错误消息那么远。没有要处理的结果,因此它可以停止让错误未读。
标签: c# sql-server sql-server-2014