c# - ExecuteScalar 是否在 SELECT 后立即返回?

标签 c# .net sql-server executescalar

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

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

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

明显的优势是性能提升(无需等待,因为结果已知),不幸的是,C# 应用程序不知道在那之后可能发生的任何 SQL 异常。

谁能证实我的解释?可以改变这种行为吗?

最佳答案

ExecuteNonQuery 方法将调用“ExecuteReader”并立即对返回的读取器对象调用“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
    

关于c# - ExecuteScalar 是否在 SELECT 后立即返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15273547/

相关文章:

c# - 算法到 "spread"在 3D 数组上递减值

c# - 更新 MongoDB 集合中的条目

c# - DSL 与方法调用 : pros and cons

c# - TabControl 中所有 TabItem 的内容相同

c# - 使用 C# 在远程 Windows 服务器上创建本地用户

sql-server - sql server 中所有数据库的默认位置在哪里

c# - 在密码字段中显示星号而不是无值

c# - 在 C# 中获取主音量

sql-server - 无法使用 Go 连接到 MS SQL Server

sql-server - 为什么 SUM(real) 在 SQL Server 中返回 float 数据类型?