受到这个问题的启发,关于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”不保存网络包或往返
我在另一个主机上使用了测试SQLServer 2017(我使用了一个虚拟机)
创建表ttable1 (n int);
插入ttable1值(1),(2),(3),(4),(5)、(6)、(7)
去
创建procNoCount过程
作为
开始
设置nocount on
更新ttable1 set n=10-n
结束
创建过程procNormal
作为
开始
更新ttable1 set n=10-n
结束
然后我用“Wireshark”工具跟踪1433端口上的数据包:
“捕获过滤器”按钮-> '端口1433'
exec procNoCount
这是响应报文:
0000 00 50 56 c0 00 08 00 0c 29 31 3f 75 08 00 45 00
0010 00 42 d0 ce 40 00 40 06 84 0d c0 a8 32 88 c0 a8
0020 32 01 05 99 fe a5 91 49 e5 9c be fb 85 01 50 18
0030 02 b4 e6 0e 00 00 04 01 00 1a 00 35 01 00 79 00
0040 00 00 00 00 fe 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
exec procNormal
这是响应报文:
0000 00 50 56 c0 00 08 00 0c 29 31 3f 75 08 00 45 00
0010 00 4f d0 ea 40 00 40 06 83 e4 c0 a8 32 88 c0 a8
0020 32 01 05 99 fe a5 91 49 e8 b1 be fb 8a 35 50 18
0030 03 02 e6 1b 00 00 04 01 00 27 00 35 01 00 ff 11
0040 00 c5 00 07 00 00 00 00 00 00 79 00 00 00 00 00
0050 fe 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00
在第40行,我可以看到'07',这是'受影响的行'的数量。
它包含在响应包中。没有额外的包裹。
然而,它有13个额外的字节可以节省,但可能并不比减少列名更值得。从“管理部门”到“总经理”)
所以我认为没有理由用它来提高性能
但
正如其他人提到的,它可以破坏ADO。网
我还无意中发现了一个使用python的问题:
MSSQL2008 - Pyodbc -以前的SQL不是查询
所以这可能还是个好习惯……
我想验证自己“SET NOCOUNT ON”不保存网络包或往返
我在另一个主机上使用了测试SQLServer 2017(我使用了一个虚拟机)
创建表ttable1 (n int);
插入ttable1值(1),(2),(3),(4),(5)、(6)、(7)
去
创建procNoCount过程
作为
开始
设置nocount on
更新ttable1 set n=10-n
结束
创建过程procNormal
作为
开始
更新ttable1 set n=10-n
结束
然后我用“Wireshark”工具跟踪1433端口上的数据包:
“捕获过滤器”按钮-> '端口1433'
exec procNoCount
这是响应报文:
0000 00 50 56 c0 00 08 00 0c 29 31 3f 75 08 00 45 00
0010 00 42 d0 ce 40 00 40 06 84 0d c0 a8 32 88 c0 a8
0020 32 01 05 99 fe a5 91 49 e5 9c be fb 85 01 50 18
0030 02 b4 e6 0e 00 00 04 01 00 1a 00 35 01 00 79 00
0040 00 00 00 00 fe 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
exec procNormal
这是响应报文:
0000 00 50 56 c0 00 08 00 0c 29 31 3f 75 08 00 45 00
0010 00 4f d0 ea 40 00 40 06 83 e4 c0 a8 32 88 c0 a8
0020 32 01 05 99 fe a5 91 49 e8 b1 be fb 8a 35 50 18
0030 03 02 e6 1b 00 00 04 01 00 27 00 35 01 00 ff 11
0040 00 c5 00 07 00 00 00 00 00 00 79 00 00 00 00 00
0050 fe 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00
在第40行,我可以看到'07',这是'受影响的行'的数量。
它包含在响应包中。没有额外的包裹。
然而,它有13个额外的字节可以节省,但可能并不比减少列名更值得。从“管理部门”到“总经理”)
所以我认为没有理由用它来提高性能
但
正如其他人提到的,它可以破坏ADO。网
我还无意中发现了一个使用python的问题:
MSSQL2008 - Pyodbc -以前的SQL不是查询
所以这可能还是个好习惯……