gsz*_*jka 5 .net c# sql-server executescalar
最近我注意到有趣的行为.
当使用SqlCommand.ExecuteScalar()运行MS SQL存储过程时,我的应用程序似乎完全不知道在SELECT完成后出现的任何SQL错误或PRINT .
最可能的解释是,在任何SELECT结果出现后立即向C#提供流控制,而不等待存储过程完成(尽管存储过程继续在下面静默执行).
显而易见的优势是性能提升(无需等待,因为结果已经知道),遗憾的是C#app并不知道在此之后可能发生的任何SQL异常.
有谁可以证实我的解释?这种行为会被改变吗?
小智 2
ExecuteNonQuery 方法将调用“ExecuteReader”并立即对返回的读取器对象调用“Close”。ExecuteScalar将调用“Read”一次,选出第一个值(索引0),然后调用“Close”。
由于 DataReader 本质上只不过是一个专门的网络流,因此在其当前位置(调用 Close 时)之后返回的任何信息将永远不会到达实际的客户端组件,即使服务器可能已发送该信息。这样的实现是为了避免在不需要时返回大量数据。
就你的情况而言,我看到了这个问题的两种解决方案。
确保您使用 ExecuteReader 来代替,并从头到尾读取结果:
using(var reader = command.ExecuteReader())
{
do
{
while (reader.Read()) { /* whatever */ };
} while (reader.NextResult());
}
Run Code Online (Sandbox Code Playgroud)如果您可以控制服务器端,则将有助于将实际的“发送到客户端”选择移动到相关过程或批次的末尾。像这样:
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
Run Code Online (Sandbox Code Playgroud)