Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 不计算使用量_Sql_Sql Server_Tsql_Ado.net_Concurrency - Fatal编程技术网

Sql 不计算使用量

Sql 不计算使用量,sql,sql-server,tsql,ado.net,concurrency,Sql,Sql Server,Tsql,Ado.net,Concurrency,灵感来源于对布景的不同看法 我们应该为SQL Server使用SET NOCOUNT ON吗?若否,原因为何 它的功能编辑6,2011年7月22日 它会在任何DML之后抑制“xx行受影响”消息。这是一个结果集,发送时,客户端必须对其进行处理。它很小,但可以测量(见下面的答案) 对于触发器等,客户端将收到多个“受影响的xx行”,这会导致某些ORM、MS Access、JPA等的各种错误(请参见下面的编辑) 背景: 一般公认的最佳实践(我一直认为在这个问题之前)是在SQL Server中的触发器和存

灵感来源于对布景的不同看法

我们应该为SQL Server使用SET NOCOUNT ON吗?若否,原因为何

它的功能编辑6,2011年7月22日

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

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

背景:

一般公认的最佳实践(我一直认为在这个问题之前)是在SQL Server中的触发器和存储过程中使用
SET NOCOUNT ON
。我们在任何地方都使用它,谷歌的快速搜索显示很多SQL Server MVP也同意这一点

MSDN说这可以打破一个错误

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

  • 如果存在以避免重复(没有行受影响的消息)注意:小心使用
  • 不存在的位置(比预期的行少
  • 过滤掉琐碎的更新(例如没有数据实际更改)
  • 执行任何表访问之前(如日志记录)
  • 隐藏复杂性或去规范化
在问题中,marc_s(谁知道他的SQL材料)说不要使用它。这与我的想法不同(我认为自己在SQL方面也有一定的能力)

我可能遗漏了什么(请随意指出显而易见的),但你们这些人怎么想

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

评论和问题后编辑:

编辑:更多想法

我们有多个客户机:一个可能使用C#SqlDataAdapter,另一个可能使用Java的nHibernate。使用
设置NOCOUNT ON
可以以不同的方式影响这些客户机

如果您将存储过程视为方法,那么假设某些内部处理以某种方式为您自己的目的工作是不正确的(反模式)

编辑2:a,其中
SET NOCOUNT ON
无法设置

(不,它不是的副本)

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

  • ,问题导致SQL 2000及更早版本上的断开连接
编辑日期:2011年5月13日

编辑日期:2011年6月14日

使用表变量中断JPA、存储过程:

编辑日期:2011年8月15日

SSMS“编辑行”数据网格要求在以下位置设置NOCOUNT:

编辑日期:2013年3月7日


来自@RemusRusanu的更深入的细节:

我想在某种程度上这是DBA与开发者之间的问题

作为一个开发人员,我要说的是,除非你绝对必须使用它,否则不要使用它——因为使用它会破坏你的ADO.NET代码(正如微软所记录的)

我想作为一名DBA,你会更倾向于另一方——尽可能地使用它,除非你真的必须阻止它的使用

此外,如果开发人员使用ADO.NET的
ExecuteOnQuery
方法调用返回的“RecordsAffected”,那么如果每个人都使用
SET NOCOUNT ON
,您就会遇到麻烦,因为在这种情况下,ExecuteOnQuery将始终返回0

也可以去看彼得·布罗姆伯格,看看他的位置

因此,这实际上可以归结为谁来制定标准:-)


马克

好的,现在我已经完成了我的研究,以下是交易:

在TDS协议中,
SET NOCOUNT-ON
仅保存,而文本“SET NOCOUNT-ON”本身的大小高达14字节。我过去认为受影响的
123行
是在单独的网络数据包中以明文形式从服务器返回的,但事实并非如此。实际上,它是一个嵌入在响应中的名为
DONE\u in\u PROC
的小结构。它不是一个单独的网络数据包,因此不会浪费往返时间

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


这里有一个非常详细的分析,说明了设置NOCOUNT的重要性:

关于破坏NHibernate的触发器,我有第一手的经验。基本上,当NH进行更新时,它希望有一定数量的行受到影响。通过将SETNOCOUNT添加到触发器,您可以将行数恢复到NH预期的值,从而解决问题。所以是的,如果你使用NH,我绝对建议关闭触发器

关于SPs中的使用,这是个人偏好的问题。我总是把排数关上,但不管怎样,都没有真正有力的论据


在一个不同的注释中,你真的应该考虑远离基于SP的体系结构,那么你甚至不会有这个问题。

< P>如果你也说你可能有不同的客户端,如果没有设置NoCube,那么经典的ADO存在问题。p> 我经常遇到的一个问题是:如果存储过程执行许多语句(从而返回许多“受影响的xxx行”消息),ADO似乎无法处理这一问题,并抛出错误“无法更改以命令对象为源的记录集对象的ActiveConnection属性”


所以我通常主张把它打开,除非有很好的理由不这样做。你可能已经找到了一个非常好的理由,我需要深入阅读。

我花了很多时间才找到NOCOUNT周围的真实基准数据,所以我想我应该分享一个简短的总结

  • 如果您的存储过程使用游标执行许多非常快速的操作,并且没有返回结果,那么禁用NOCOUNT可能会导致错误
    SET NOCOUNT ON;
    
    CREATE PROCEDURE NoCountOn
    AS
    set nocount on
        DECLARE @num INT = 10000
        while @num > 0
        begin
           update MyTable SET SomeColumn=SomeColumn
           set @num = @num - 1
        end
    GO
    
    
    CREATE PROCEDURE NoCountOff
    AS
    set nocount off
        DECLARE @num INT = 10000
        while @num > 0
        begin
           update MyTable SET SomeColumn=SomeColumn
           set @num = @num - 1
        end
    GO
    
    SET NOCOUNT ON
    
    DECLARE @test TABLE (ID int)
    
    INSERT INTO @test
    VALUES (1),(2),(3)
    
    DECLARE @affectedRows int = -99  
    
    DELETE top (1)
      FROM @test
    SET @affectedRows = @@rowcount
    
    SELECT @affectedRows as affectedRows