0

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

我还发现了一篇关于使用 SQL 提示查找代码异味的有趣博客:SET NOCOUNT 问题(PE008 和 PE009),它确实涉及了一些有趣的细节,但仍然没有回答我的问题。

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

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

因此,我的问题主要集中在 C# 中的SqlCommand.ExecuteNonQuery 方法上,因为它依赖于以下事实:

对连接执行 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

4

1 回答 1

1

大约十年前,我开始使用SqlCop,它曾经突出显示“没有 SET NOCOUNT ON 的程序”。随着时间的推移,我已经进化了,所以我不再使用它,但我喜欢这个概念,所以我有一组单元测试,它们运行元数据查询来查找像 SqlCop 用来突出显示的东西(以及更多)。

我的每个测试都允许我为每个规则添加排除项,这允许我在评论中记录排除它的理由。

我目前对此的测试(我不必亲自动手)可能会突出显示包含SELECT但不包含SET NOCOUNT ON. 这样,INSERTs、UPDATEs 和DELETEs 都保留了默认行为,允许我的代码使用ExecuteNonQuery. 任何边缘情况都可以从规则中排除。

这使我可以让 SQL 服务器保持默认行为,并且我的应用程序的 SP 可以选择何时与 Microsoft 的默认值不同。

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

这是一个非常明智的建议,因为事后诸葛亮是一件好事:如果您知道可以更改默认值,您只会知道需要设置它。有点像您了解到将 SP 脚本编写为“IF EXISTS、DROP 和 CREATE”(SSMS 提供了如此有用的功能)是一种愚蠢的做法:最好仅 IF NOT EXISTS 创建一个占位符,然后将其更改为实际定义(避免丢失元数据,如权限)。

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

无论您决定采用哪种方式,我只是觉得这种通过单元测试来执行您决定的方法的技术是非常宝贵的。检查每个 SP 是否总是以一种或另一种方式设置它似乎是明智的。

于 2018-09-17T17:52:16.280 回答