受到这个问题的启发,关于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真的有这么大的性能差异吗


当前回答

If(设置no count== off)

{ 然后,它将保存受影响记录数量的数据 降低性能 } 其他的 { 它不会跟踪变更记录 因此提高绩效 } }

其他回答

Sometimes even the simplest things can make a difference. One of these simple items that should be part of every stored procedure is SET NOCOUNT ON. This one line of code, put at the top of a stored procedure turns off the messages that SQL Server sends back to the client after each T-SQL statement is executed. This is performed for all SELECT, INSERT, UPDATE, and DELETE statements. Having this information is handy when you run a T-SQL statement in a query window, but when stored procedures are run there is no need for this information to be passed back to the client.

通过从网络中移除这种额外的开销,可以极大地提高数据库和应用程序的整体性能。

如果您仍然需要获得受正在执行的T-SQL语句影响的行数,您仍然可以使用@@ROWCOUNT选项。通过发出SET NOCOUNT ON,这个函数(@@ROWCOUNT)仍然可以工作,并且仍然可以在存储过程中使用,以确定有多少行受到语句的影响。

我想在某种程度上这是一个DBA vs.开发人员的问题。

作为一个开发人员,我会说除非你绝对有必要,否则不要使用它——因为使用它会破坏你的ADO。NET代码(如Microsoft文档所示)。

我想作为一名DBA,您应该站在另一边——只要有可能就使用它,除非您真的必须阻止它的使用。

同样,如果你的开发者使用了ADO返回的“RecordsAffected”。NET的ExecuteNonQuery方法调用,如果每个人都使用SET NOCOUNT ON,您就会遇到麻烦,因为在这种情况下,ExecuteNonQuery总是返回0。

也可以看看Peter Bromberg的博客文章,看看他的立场。

所以归根结底是谁来制定标准:-)

Marc

当SET NOCOUNT为ON时,计数(指示受Transact-SQL语句影响的行数)不会返回。当SET NOCOUNT为OFF时,返回计数。它与任何SELECT, INSERT, UPDATE, DELETE语句一起使用。 SET NOCOUNT的设置在执行或运行时设置,而不是在解析时设置。 SET NOCOUNT ON可提高SP (storage procedure)性能。 语法:SET NOCOUNT {ON | OFF}

SET NOCOUNT ON示例:

SET NOCOUNT OFF示例:

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

在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/

如果你说你可能有不同的客户端,经典的ADO有问题,如果SET NOCOUNT没有设置为ON。

我经常遇到的一个问题是:如果一个存储过程执行了许多语句(因此返回了许多“受影响的xxx行”消息),ADO似乎没有处理这个问题,并抛出错误“无法更改以Command对象作为源的记录集对象的ActiveConnection属性”。

所以我一般建议打开它,除非有非常非常好的理由不打开。你可能已经找到了非常非常好的理由,我需要进一步阅读。