【问题标题】:Does SqlCommand.ExecuteReader / SqlDataReader.Read swallow exceptions?SqlCommand.ExecuteReader / SqlDataReader.Read 会吞下异常吗?
【发布时间】:2015-11-28 11:16:54
【问题描述】:

考虑以下代码:

namespace SqlExceptionTest
{
    using System;
    using System.Data.SqlClient;

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var sql =
    @"BEGIN TRY
    SELECT 1;
    THROW 50000, 'An error occured.', 1;
END TRY
BEGIN CATCH
     THROW
END CATCH
";

                using (var cnn = new SqlConnection("<totally valid connection string>"))
                using (var cmd = new SqlCommand(sql, cnn))
                {
                    cnn.Open();

                    using (var r = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow))
                    {
                        do
                        {
                            while (r.Read())
                            {
                                // do something
                            }
                        } while (r.NextResult());

                        r.Close();
                    }

                    cnn.Close();
                }

                Console.WriteLine("Code executed without any issues.");
            }
            catch
            {
                Console.WriteLine("An exception was raised");
            }
            finally
            {
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
}

(我知道这里的T-Sql代码没有意义,只是为了演示。)

我原以为上面的代码会抛出一个SqlException 实例,但显然它没有。相反,while 块通常循环到最后,连接关闭,程序结束。我尝试在框架 v2 上编译到 4.6,每次都得到相同的结果。

我是否有办法,仅在 .NET 中(不更改 T-Sql 代码)使用SqlDataReader 并且知道发生错误之后 em> SELECT 声明结束了?还是它永远消失在 ADO.NET 的机制中?

【问题讨论】:

  • 离题提示 #1:C# 支持多行字符串文字:使用 @"..."(可以包括换行符)而不是 StringBuilder
  • 离题提示 #2:在您的数据阅读器 r 周围放置一个 using 块。
  • 使用 ExecuteNonQuery 将在 C# 中触发带有预期消息的 SqlException
  • 由于System.Data.CommandBehavior.SingleRow,正在琢磨是否是优化。
  • 是的。我用 SS2008R2 和RaIsError 确认了几分钟。我冒昧地将其发布为答案。

标签: c# .net tsql exception ado.net


【解决方案1】:

指定System.Data.CommandBehavior.SingleRow 允许读取结果集,而不会在应用程序中引发后续异常。 System.Data.CommandBehavior.SingleResult 提供相同的优化

【讨论】:

  • 一定是因为优化使 ADO.NET 在完成读取它被告知的一行/结果后立即停止侦听任何更多的 Sql Server 消息。因此,它无法意识到稍后发生的错误。有道理。
  • @RezaAghaei 诚然,我回到了 VS2010 和 SS2008R2 的黑暗时代,但我正在运行代码。当查询更改为SELECT 1 / 0 AS X; 并且应用程序在最内层循环中执行Console.WriteLine((int)r["X"]); 时,这种行为就更加奇怪了。没有例外,也没有任何一个麻烦的 CommandBehavior 选项返回行。
  • @HABO 你是对的,我对这种行为感到困惑。因此,我将删除该帖子,以免误导其他用户,同时它具有一些有用的事实。似乎需要更多的研究。无论如何,我感谢你和克罗诺的这次如此有用的谈话,至少对我来说:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2018-08-25
  • 2018-05-26
  • 2012-03-06
  • 2012-06-22
  • 1970-01-01
相关资源
最近更新 更多