gbn*_*gbn 320 sql t-sql sql-server concurrency ado.net
灵感来自这个问题,对于SET NOCOUNT有不同的看法......
我们应该为SQL Server使用SET NOCOUNT ON吗?如果没有,为什么不呢?
它的作用编辑6,2011年7月22日
它会在任何DML之后抑制"xx行受影响"消息.这是一个结果集,当发送时,客户端必须处理它.它很小,但可以测量(见下面的答案)
对于触发器等,客户端将收到多个"受影响的xx行",这会导致某些ORM,MS Access,JPA等出现各种错误(参见下面的编辑)
背景:
一般接受的最佳实践(我想直到这个问题)是SET NOCOUNT ON
在SQL Server中的触发器和存储过程中使用.我们在任何地方都使用它,快速谷歌显示大量的SQL Server MVP也同意.
MSDN表示这可能会破坏.net SQLDataAdapter.
现在,这对我来说意味着SQLDataAdapter仅限于完全简单的CRUD处理,因为它希望"n行受影响"消息匹配.所以,我不能用:
在问题marc_s(谁知道他的SQL的东西)说不要使用它.这与我的想法不同(我认为自己在SQL方面也有一定的能力).
有可能我错过了一些东西(随意指出明显的东西),但你们有什么想法呢?
注意:我看到这个错误已经好几年了,因为我现在不使用SQLDataAdapter.
在评论和问题后编辑:
编辑:更多想法......
我们有多个客户端:一个可以使用C#SQLDataAdaptor,另一个可以使用Java中的nHibernate.这些可能会以不同的方式受到影响SET NOCOUNT ON
.
如果您将存储过程视为方法,那么假设某些内部处理以某种方式为您自己的目的而工作则是不好的形式(反模式).
编辑2:触发器打破nHibernate问题,SET NOCOUNT ON
无法设置
(不,它不是一个重复的这个)
编辑3:更多信息,感谢我的MVP同事
编辑2011年5月13日
编辑2011年6月14日
使用表变量打破JPA,存储过程:JPA 2.0是否支持SQL Server表变量?
编辑6:2011年8月15日
SSMS"编辑行"数据网格需要SET NOCOUNT ON:使用GROUP BY更新触发器
编辑2013年3月7日7:07
来自@RemusRusanu的更深入的细节:
SET NOCOUNT ON是否真的产生了很大的性能差异
Sed*_*glu 230
好了,我已经完成了我的研究,这是交易:
在TDS协议中,每个查询SET NOCOUNT ON
只保存9个字节,而文本"SET NOCOUNT ON"本身是高达14个字节.我曾经认为这123 row(s) affected
是从一个单独的网络数据包中以纯文本形式从服务器返回的,但事实并非如此.事实上,它是一个称为DONE_IN_PROC
嵌入在响应中的小结构.它不是一个单独的网络数据包,因此不会浪费往返.
我认为你几乎总是可以坚持默认的计数行为而不用担心性能.但是在某些情况下,事先计算行数会影响性能,例如只向前游标.在这种情况下,NOCOUNT可能是必需的.除此之外,绝对没有必要遵循"尽可能使用NOCOUNT"的座右铭.
以下是关于SET NOCOUNT
设置无关紧要的非常详细的分析:http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount/
Bha*_*tel 73
当SET NOCOUNT为ON时,不返回计数(指示受Transact-SQL语句影响的行数).当SET NOCOUNT为OFF时,返回计数.它与任何SELECT,INSERT,UPDATE,DELETE语句一起使用.
SET NOCOUNT的设置在执行或运行时设置,而不是在分析时设置.
SET NOCOUNT ON可提高存储过程(SP)性能.
语法:SET NOCOUNT {ON | 关闭}
SET NOCOUNT ON的示例:
SET NOCOUNT OFF的示例:
mar*_*c_s 33
我想在某种程度上这是一个DBA与开发人员问题.
作为一个开发人员,我会说不要使用它,除非你绝对肯定 - 因为使用它可能会破坏你的ADO.NET代码(如微软记录的那样).
我想作为一名DBA,你会更多地在另一方面 - 尽可能使用它,除非你真的必须阻止它的使用.
此外,如果您的开发人员曾使用ADO.NET的ExecuteNonQuery
方法调用返回的"RecordsAffected" ,那么如果每个人都使用,那么SET NOCOUNT ON
在这种情况下,ExecuteNonQuery将始终返回0.
另见Peter Bromberg的博客文章并查看他的立场.
所以它真的归结为谁设定标准:-)
渣
Chr*_*s J 11
如果你说你可能也有不同的客户端,如果SET NOCOUNT未设置为ON,则经典ADO会出现问题.
我经常遇到的一个问题是:如果存储过程执行了许多语句(因此返回了许多"受xxx行影响"的消息),ADO似乎不会处理这个并抛出错误"无法更改Recordset对象的ActiveConnection属性它有一个Command对象作为源."
所以我一般都主张将它设置为ON,除非有一个非常好的理由不这样做.你可能已经找到了我需要去阅读更多内容的真正原因.
冒着使事情变得更复杂的风险,我鼓励对我上面看到的所有人略有不同的规则:
NOCOUNT ON
在一个进程的顶部,在此之前在proc任何工作,但也 总是SET NOCOUNT OFF
再次,从存储过程返回记录集的任何之前.所以"通常保持nocount,除非你实际返回结果集".我不知道这会破坏任何客户端代码的任何方式,这意味着客户端代码永远不需要了解有关proc内部的任何信息,并且它并不特别繁重.
关于打破NHibernate的触发器,我亲身体验过这种体验.基本上,当NH执行UPDATE时,它会受到一定数量的行影响.通过将SET NOCOUNT ON添加到触发器,您可以将行数返回到NH预期的范围,从而解决问题.所以是的,如果你使用NH,我肯定会建议将其关闭.
关于SP中的使用,这是个人偏好的问题.我总是关掉行数,但话说再说,无论如何都没有真正强烈的争论.
另外一点,你应该考虑从基于SP的架构转移,然后你甚至不会有这个问题.
归档时间: |
|
查看次数: |
252776 次 |
最近记录: |