首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中捕获RAISERROR

在C#中捕获RAISERROR
EN

Stack Overflow用户
提问于 2017-07-24 21:52:20
回答 2查看 3.1K关注 0票数 1

我试图为这个问题找到一个有用的答案,但失败了(我发现最近的答案是)。我有一个C#应用程序调用一个存储过程,它使用SQL TRY/CATCH来处理错误。我可以用这样的样例存储过程来复制这个问题:

代码语言:javascript
复制
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

然后一个像这样的小程序:

代码语言:javascript
复制
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返回数据的过程。也许答案是“不要那样做”,但最好知道是否有一种方法可以在获取结果时简单地捕捉错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-24 22:13:45

原因是因为引发错误是在数据读取器中的第一个结果集结束之后,并且只有在数据读取器上调用NextResult()时才会得到错误!

当使用SqlDataReader时,它只会迭代第一个结果集,在本例中,这将是存储过程中的选择。

试着查看更多细节这里

代码语言:javascript
复制
using (SqlDataReader rdr = cmd.ExecuteReader())
{
    while (!rdr.IsClosed())
    {   
        while (rdr.Read())
        {
            Console.WriteLine(rdr.GetValue(0).ToString());
        }

        if (!rdr.NextResult())
        {
            rdr.Close();
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-07-24 22:11:40

我可以提出三项建议:

  1. 使用CommandType.Text而不是CommandType.StoredProcedure。现在可能已经修复了这个问题,但几年前,我发现CommandType.StoredProcedure总是将消息输出缓冲为大约50次,而CommandType.Text则允许消息立即返回到C#。
  2. WITH NOWAIT提示添加到RAISERROR代码中。
  3. 不要忘记FireInfoMessageEventOnUserErrors属性。您确实希望处理InfoMessage事件。

我不确定这些能解决你的问题,但它们应该给你一些方向。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45290672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档