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中用於不返回執行查詢時受影響的數字行。 如果我們不需要受影響的行數,我們可以使用它,因為這將有助於節省內存使用量並提高查詢執行的速度。