C#SqlCommand.ExecuteNonQuery()和SQL SET NOCOUNT ON

时间:2018-09-17 15:27:29

标签: c# sql-server nocount

我整个下午都在搜索,不相信这与其他ExecuteNonQuery() and SET NOCOUNT ON浮动的问题是重复的。

我还找到了一个有关Finding code smells using SQL Prompt: the SET NOCOUNT problem (PE008 and PE009)的有趣博客,该博客确实涉及了一些有趣的细节,但仍然没有回答我的问题。

我有一个数据库服务器,管理员在其中选中了服务器连接的no count选项(在SSMS中,右键单击“对象资源管理器”中的服务器,转到“属性”,选择“连接”页面,在“默认连接”下选项”,向下滚动直到找到“无计数”选择器)。

根据我所做的所有阅读,越来越多的管理员可能会勾选no count选项以提高性能,因为结果行将不再发送回客户端。

因此,我的问题主要针对C#中的SqlCommand.ExecuteNonQuery Method,因为它依赖于以下事实:

  

针对该连接执行Transact-SQL语句,并 返回受影响的行数

但是如果强制执行SET NOCOUNT ON,则结果将始终为-1。我已经读过有关人们如何推荐而不是使用select @rowcount = @@ROWCOUNT的建议,但这并不能弥补您从SqlCommand.ExecuteNonQuery方法中失去功能的事实,甚至您可能刚开始就无法使用它。而是使用SqlCommand.ExecuteScalar

因此,我的问题是,为了最佳实践,我们是否应该开始将SQL Server设置为no count(或者至少希望这是它们将在未来几年内开始配置它们的方式),然后如果是这样,我们应该强迫SET NOCOUNT OFF还是放弃SqlCommand.ExecuteNonQuery来支持select @rowcount = @@ROWCOUNT

1 个答案:

答案 0 :(得分:0)

大约十年前,我开始使用SqlCop,它通常用于突出显示“不设置NOCOUNT ON的过程”。随着时间的推移,我已经发展了,因此不再使用它,但是我喜欢这个概念,所以我有一组单元测试,这些单元测试运行元数据查询来查找诸如SqlCop之类用于突出显示的内容(以及更多内容)。

我的每项测试都允许我在每个规则中添加排除项,从而可以在注释中记录排除该理由的理由。

我对此的当前测试(我不必手动进行)可能会突出显示包含SELECT但不包含SET NOCOUNT ON的存储过程。这样,INSERTUPDATEDELETE都保留了默认行为,从而使我的代码可以使用ExecuteNonQuery的结果。任何附带情况都可以排除在规则之外。

这使我可以使SQL Server保留默认行为,而我的应用程序的SP选择何时与Microsoft的默认行为有所不同。

请注意,如果有人修改了默认设置,那么我的代码将无法工作,因为我没有遵循 RedGate文章结尾处的建议”查询返回行计数消息,您应该指定它,而不是采用当前设置。”

这是非常明智的建议,从某种意义上说,事后看来是一件很了不起的事情:只有知道默认值可以更改时,您才知道需要设置它。有点像您了解到将SP脚本编写为“ IF EXISTS,DROP和CREATE”(因此SSMS提供 helpful )是一种愚蠢的做法:如果不存在,则最好创建一个占位符,然后然后将其更改为实际定义(避免丢失元数据,如权限)。

我当然可以修复我的SP,并添加新的或更改的单元测试,以确保我始终以一种或另一种方式设置NOCOUNT选项。但是我要说的是,如果将行为设置为不同于默认行为也可能破坏您在该服务器上安装的任何第三方产品,这不会令我感到惊讶。 (也许这与您的情况无关紧要。)

无论您决定采用哪种方式,我都只是觉得采用单元测试来执行您决定的方法的这种技术是非常宝贵的。检查每个SP始终设置为一种方式还是另一种方式似乎是明智的。