在SELECT之后,ExecuteScalar会立即返回吗?

时间:2013-03-07 14:19:02

标签: c# .net sql-server executescalar

最近我注意到有趣的行为。

当使用 SqlCommand.ExecuteScalar()运行MS SQL存储过程时,我的应用程序似乎完全不知道在 SELECT 之后出现的任何SQL错误或PRINT完成。

最可能的解释是,在任何SELECT结果出现后立即向C#提供流控制,而不等待存储过程完成(尽管存储过程继续在下面静默执行)。

明显的优势是性能提升(无需等待,因为结果已经知道),遗憾的是C#app并不知道在此之后可能发生的任何SQL异常。

有人能证实我的解释吗?这种行为会被改变吗?

1 个答案:

答案 0 :(得分:2)

ExecuteNonQuery方法将调用“ExecuteReader”并立即在返回的reader对象上调用“Close”。 ExecuteScalar将调用“Read”一次,选出第一个值(索引0),然后调用“Close”。

由于DataReader实际上只不过是一个专门的网络流,因此,当它的当前位置(调用Close时)返回的任何信息都将永远不会到达实际的客户端组件,即使服务器可能

在您的情况下,我看到了解决此问题的两种方法。

  1. 请确保您改为使用ExecuteReader,并一直读取结果:

    using(var reader = command.ExecuteReader())
    {
        do 
        {
              while (reader.Read()) { /* whatever */ };
        } while (reader.NextResult());
    }
    
  2. 如果您可以控制服务器端,它将有助于将实际的“发送到客户端”选择移动到相关过程或批处理的末尾。像这样:

    create proc Demo
    as
    declare @result int
    select top 1 @result = Id from MyTable where Name = 'testing'
    print 'selected result...'
    select @result Id  -- will send a column called "Id" with the previous value
    go