【发布时间】:2018-09-17 15:27:29
【问题描述】:
我已经搜索了整个下午,但我不认为这与像 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?
【问题讨论】:
-
我很确定没有
no count选项这样的东西。有SET NOCOUNT ON,第三方产品中可能有一个选项,相当于“当我检查这个时自动发出SET NOCOUNT ON”(Management Studio 有这样一个选项),但是没有 SQL Server 默认值(嗯,@987654337 @ 是默认值)。存储过程通常以SET NOCOUNT ON开头,但这是另一回事。这个no count选项应该在哪里管理员勾选? -
换一种说法,如果你给数据库设置了一个
SqlConnection(没有特殊关键字),然后你发出一个SqlCommand,上面写着DECLARE @T TABLE(ID INT); INSERT @T DEFAULT VALUES,那么ExecuteNonQuery是什么意思?给你?无论任何 SQL Server 设置如何,它都应该是1。换句话说,SET NOCOUNT仍然是执行查询的选择。 -
啊,等等,我错了! 有一种将
NOCOUNT ON设为默认值的方法,它涉及调用sp_configure 'user options', 512。 (我的 Management Studio 版本没有用于此的 UI,但我想某些版本可能。)在此之后,您确实会观察到NOCOUNT有效,并且所有ExecuteNonQuery调用都给出-1,除非明确的SET NOCOUNT OFF首先发出。就像出厂默认设置的任何更改会更改 SQL 语义一样,我强烈建议不要这样做,无论声称的收益如何——开发人员不会期望它。 -
对于“最佳实践”,我想说:如果您需要计数,请使用 either 目标
SET NOCOUNT OFF或@@ROWCOUNT,正如您认为合适的那样——一个并不比另一个优越。但相反,在服务器端,最佳实践是保留连接默认值,以便写入默认值(大部分)的软件不会无缘无故地中断。我怀疑是否有人彻底测试了实际的性能提升,并将其与更改软件的成本进行了比较,包括您的管理员。在 SQL Server 上要优化的所有内容中,NOCOUNT的排名靠后。 -
谢谢,我发现了。现在我知道如何更改默认值,我知道我永远不会做额外的内容。在任何服务器上。尽管我真的不介意,例如,从可管理性的角度来看,
XACT_ABORT默认为ON,但破坏软件的风险太大,并且不会超过潜在的好处。您可以该死确定,只要 SQL Server 继续支持某个选项,Microsoft 也不会触及这些默认值——当然不会NOCOUNT。
标签: c# sql-server nocount