sql - stored - trigger nocount




SET NOCOUNT ON用法 (8)

受到SET NOCOUNT有不同觀點的這個問題的啟發...

我們應該使用SQL Server的SET NOCOUNT ON嗎? 如果不是,為什麼不呢?

它的作用編輯6,2011年7月22日

它會在任何DML之後抑制“xx rows affected”消息。 這是一個結果集,當發送時,客戶端必須處理它。 它很小,但是可以測量(見下面的答案)

對於觸發器等,客戶端將收到多個“受影響的xx行”,這會導致某些ORM,MS Access,JPA等的所有錯誤形式(請參閱下面的編輯)

背景:

一般接受的最佳實踐(我認為直到這個問題)是在SQL Server中的觸發器和存儲過程中使用SET NOCOUNT ON 。 我們在任何地方都使用它,並且快速的谷歌顯示了許多SQL Server MVP也同意。

MSDN表示這可能會破壞.net SQLDataAdapter

現在,這對我意味著SQLDataAdapter僅限於完全簡單的CRUD處理,因為它期望“n行受影響”消息匹配。 所以,我不能使用:

  • 如果存在以避免重複(不受行影響的消息) 注意:謹慎使用
  • 不存在(更少的行然後預期
  • 過濾掉微不足道的更新(例如,實際上沒有數據發生變化)
  • 做任何表訪問之前(如日誌記錄)
  • 隱藏複雜性或denormlisation
  • 等等

在問題marc_s(誰知道他的SQL的東西)說,不要使用它。 這與我認為的不同(我也認為我自己在SQL方面也有點勝任)。

這可能是我錯過了一些東西(隨意指出明顯的),但是你認為那裡有什麼?

注意:我看到這個錯誤已經有好幾年了,因為我現在不使用SQLDataAdapter。

評論和問題後編輯:

編輯:更多的想法...

我們有多個客戶端:一個可以使用C#SQLDataAdaptor,另一個可以使用Java的nHibernate。 SET NOCOUNT ON可能會以不同的方式影響這些SET NOCOUNT ON

如果你將存儲過程視為方法,那麼為了你自己的目的,假定某些內部處理以某種方式工作,那麼這是糟糕的形式(反模式)。

編輯2: 打破nHibernate問題觸發器 ,其中SET NOCOUNT ON無法設置

(並且不,它不是重複的)

編輯3:更多信息,感謝我的MVP同事

編輯2011年5月13日

沒有指定時也打破Linq 2 SQL?

編輯5:14六月2011

使用表變量中斷JPA,存儲過程: JPA 2.0是否支持SQL Server表變量?

編輯6:15八月2011

SSMS“編輯行”數據網格需要SET NOCOUNT ON: 使用GROUP BY更新觸發器

編輯7:07 Mar 2013

更多來自@RemusRusanu的深度細節:
SET NOCOUNT ON是否真的使性能有很大的不同


SET NOCOUNT ON; 以上代碼將在DML / DDL命令執行後將由SQL Server引擎生成的消息停止到前端結果窗口。

我們為什麼這樣做? 由於SQL服務器引擎需要一些資源來獲取狀態並生成消息,因此它被認為是Sql服務器引擎的重載。因此,我們設置了非計數消息。


冒著讓事情變得更加複雜的風險,我鼓勵對上述所有人採取稍微不同的規則:

  • 在proc中執行任何操作之前,總是在proc的頂部設置NOCOUNT ON ,但在從存儲過程返回任何記錄集之前,總是要再次SET NOCOUNT OFF

所以“通常保持nocount,除非你實際返回結果集”。 我不知道這會破壞任何客戶端代碼的任何方式,這意味著客戶端代碼永遠不需要知道任何關於proc內部的東西,而且它並不是特別繁重。


如果你說你可能有不同的客戶端,如果SET NOCOUNT沒有設置為ON,那麼傳統的ADO會出現問題。

我經常遇到一個問題:如果一個存儲過程執行一些語句(並因此返回一些“xxx rows affected”消息),ADO似乎不處理這個問題並引發錯誤“無法更改Recordset對象的ActiveConnection屬性其中有一個Command對像作為其源。“

所以我通常主張將其設置為ON,除非有真正的理由不這樣做。 你可能已經找到了真正的好理由,我需要去閱讀更多內容。


如果(設置不計數== off)

{那麼它會保存多少記錄受影響的數據,因此降低性能} else {它不會跟踪變化的記錄,從而改善性能}}


我猜在某種程度上這是一個DBA vs.開發人員問題。

作為開發者,我會說不要使用它,除非你絕對必須這樣做 - 因為使用它可能會破壞你的ADO.NET代碼(如Microsoft所記錄的)。

我想作為一名DBA,你會在另一邊更加努力 - 盡可能地使用它,除非你真的必須阻止它的使用。

另外,如果您的開發人員使用ADO.NET的ExecuteNonQuery方法調用返回的“RecordsAffected”,那麼如果每個人都使用SET NOCOUNT ON ,則會遇到問題,因為在這種情況下,ExecuteNonQuery將始終返回0。

另見Peter Bromberg的博客文章,並查看他的位置。

所以這真的歸結為誰來設置標準:-)

渣子


我知道這是一個很老的問題。 但只是為了更新。

使用“SET NOCOUNT ON”的最佳方法是將其作為第一條語句放在SP中,並在最後一條SELECT語句之前再次將其設置為OFF。


關於打破NHibernate的觸發器,我親身體驗了這種體驗。 基本上,當NH進行更新時,它期望受到一定數量的行影響。 通過將SET NOCOUNT ON添加到觸發器,可以將行數返回到NH預期的數量,從而解決問題。 所以是的,如果你使用NH,我肯定會推薦關閉觸發器。

關於SP中的使用情況,這是個人偏好的問題。 我一直在排倒數,但再一次,沒有任何真正有力的論據。

另一方面,你應該考慮從基於SP的架構中移走,那麼你甚至不會有這個問題。


SET NOCOUNT ON;

這行代碼在SQL中用於不返回執行查詢時受影響的數字行。 如果我們不需要受影響的行數,我們可以使用它,因為這將有助於節省內存使用量並提高查詢執行的速度。







concurrency