ExecuteNonQuery()和SET NOCOUNT ON

时间:2015-04-16 15:46:26

标签: c# sql-server ado.net

我使用的是MS SQL Server 2008 R2 我有一个C#应用程序 - 它的客户端。 我遇到了以下错误(仍然无法重现它。以下客户端代码带来了“受影响的行数”超过它应该:

…
DbCommand cmd = db.GetStoredProcCommand("TheStoredProc");
int numberOfAffectedRows = db.ExecuteNonQuery(cmd);
…

DB中的存储过程TheStoredProc如下所示:

PROCEDURE TheStoredProc 
as

    declare @Var1 int

    **SET NOCOUNT ON;**
…
insert into [Workflows]
    (
        WorkflowInstanceID,
        Status
    )
    select WorkflowInstanceID, 1
        from #tmp


    DROP TABLE #tmp

这是继承的代码;我不是它的作者。但是从上下文我看到 - 客户端期望ExecuteNonQuery带来“插入[Workflows] ...”操作符所插入的行数。

仅通过此运算符INSERT。 proc之前还包含一个INSERT;但客户需要numberOfAffectedRows填充“插入[工作流程] ...”所插入的行数。

错误如下:numberOfAffectedRows得到了值464.但是从数据库内容我看到它应该是419.而且这个错误是不可重复的 - 直到我在Productions erver上看到它只有一次;仍然无法在我的测试服务器上重现它。在测试服务器上,numberOfAffectedRows是正确的。

我有以下版本:错误的原因是“SET NOCOUNT ON”inboredStored的开头。 Here我发现了同样的问题:

  

...我听说使用" SET NOCOUNT ON"一个。   SQLCommand.ExecuteNonQuery函数返回错误的行数if   存储过程已设置为SET NOCOUNT。 ...

更常见的是(在其他论坛上)我遇到了在这种情况下由ExecuteNonQuery返回(-1)的抱怨。

你怎么想 - 我是对的吗?

错误修正应该如下:在“插入[工作流程] ...”之前插入“SET NOCOUNT OFF”。在我的测试服务器上,这可以正常工作 - 但是初始代码在测试服务器上也能正常工作......

1 个答案:

答案 0 :(得分:3)

我认为将SET NOCOUNT设为ON将始终返回-1(可能存在不是真的情况,但是......)

ExecuteNonQuery计算插入/更新所影响的行数,以及因触发器而修改的所有行。您是否在测试或生产数据库中受影响的表上有任何可能表现不同的触发器?

您有什么理由不想明确返回您感兴趣的行数吗?例如,更改在您感兴趣的插入后添加此内容:

select @rowcount = @@ROWCOUNT

然后返回@rowcount值,或者在输出参数中传回。看起来这样做可以防范您,以防稍后添加触发器导致您的计数发生变化而不会对系统功能产生重大影响。