受到这个问题的启发,关于SET NOCOUNT有不同的观点…

我们应该使用SET NOCOUNT ON SQL Server吗?如果不是,为什么不是?

它的作用编辑6,2011年7月22日

它在任何DML之后抑制“受影响的xx行”消息。这是一个结果集,当发送时,客户端必须处理它。它很小,但可测量(见下面的答案)

对于触发器等,客户端将收到多个“受影响的xx行”,这将导致一些orm, MS Access, JPA等的各种错误(见下面的编辑)

背景:

一般公认的最佳实践(我认为直到这个问题)是在SQL Server的触发器和存储过程中使用SET NOCOUNT ON。我们到处使用它,快速谷歌显示大量的SQL Server mvp也同意。

MSDN说这会破坏。net SQLDataAdapter。

现在,这对我来说意味着SQLDataAdapter仅限于完全简单的CRUD处理,因为它期望匹配“受影响的n行”消息。所以,我不能用:

IF EXISTS以避免重复(没有行影响消息)注意:谨慎使用 WHERE不存在(行数比预期的少 过滤掉琐碎的更新(例如没有数据实际变化) 在之前进行任何表访问(例如日志记录) 隐藏复杂性或去规范化 等

在这个问题中marc_s(谁知道他的SQL东西)说不要使用它。这与我的想法不同(我认为自己在SQL方面也有一定的能力)。

我可能遗漏了一些东西(尽管指出显而易见的事实),但你们怎么看?

注意:我已经好几年没有看到这个错误了,因为我现在不使用SQLDataAdapter。

评论和问题后的编辑:

编辑:更多想法…

我们有多个客户端:一个可能使用c# SQLDataAdaptor,另一个可能使用来自Java的nHibernate。这些可以通过SET NOCOUNT ON以不同的方式受到影响。

如果您将存储的proc视为方法,那么假定某些内部处理以某种方式为您自己的目的是不合适的(反模式)。

编辑2:一个触发中断nHibernate问题,其中SET NOCOUNT ON不能设置

(不,它不是这个的副本)

编辑3:更多信息,感谢我的MVP同事

KB 240882,在SQL 2000和更早的版本上导致断开连接的问题 性能增益演示

编辑4:2011年5月13日

打破linq2 SQL太当没有指定?

编辑5:14 2011年6月

打破JPA,存储过程与表变量:JPA 2.0支持SQL Server表变量吗?

编辑6:15 2011年8月

SSMS“编辑行”数据网格需要SET NOCOUNT ON:用GROUP BY更新触发器

编辑7: 07 Mar 2013

更深入的细节来自@RemusRusanu: SET NOCOUNT ON真的有这么大的性能差异吗


当前回答

我知道这是个很老的问题。只是更新一下。

使用“SET NOCOUNT ON”的最佳方法是将其作为SP中的第一个语句,并在最后一个SELECT语句之前再次将其设置为OFF。

其他回答

我不知道如何在客户端和SQL之间测试SET NOCOUNT ON,所以我测试了其他SET命令的类似行为“SET TRANSACTION ISOLATION LEVEL READ unimcommitted”

我从我的连接发送了一个命令,改变SQL的默认行为(READ COMMITTED),它被更改为下一个命令。 当我在存储过程中更改ISOLATION级别时,它不会更改下一个命令的连接行为。

目前的结论,

在存储过程中更改设置不会更改连接默认设置。 通过使用ADOCOnnection发送命令更改设置将更改默认行为。

我认为这与其他SET命令相关,如“SET NOCOUNT ON”

我知道这是个很老的问题。只是更新一下。

使用“SET NOCOUNT ON”的最佳方法是将其作为SP中的第一个语句,并在最后一个SELECT语句之前再次将其设置为OFF。

设置nocount on; 以上代码将在DML/DDL命令执行后,停止sql server引擎生成的消息到前端结果窗口。

我们为什么要这么做? 由于SQL server引擎获取状态并生成消息需要消耗一定的资源,因此对SQL server引擎来说是一种过载。所以我们设置了noncount消息。

SET NOCOUNT ON-将显示“Command(s) completed successfully”。 SET NOCOUNT OFF-它将显示”(No。受影响的行)”。

好了,现在我做了我的研究,事情是这样的:

在TDS协议中,SET NOCOUNT ON每次查询只节省9个字节,而文本“SET NOCOUNT ON”本身是一个巨大的14个字节。我曾经认为受影响的123行是在一个单独的网络数据包中以纯文本从服务器返回的,但事实并非如此。实际上,它是嵌入在响应中的一个名为DONE_IN_PROC的小结构。它不是一个单独的网络数据包,因此不会浪费往返。

我认为您几乎总是可以坚持默认的计数行为,而不用担心性能。但是在某些情况下,预先计算行数会影响性能,例如只向前游标。在这种情况下,NOCOUNT可能是必需的。除此之外,绝对没有必要遵循“尽可能使用NOCOUNT”的座右铭。

这里有一个关于SET NOCOUNT设置不重要的非常详细的分析:http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount/