Now, is set nocount off necessary? No, as any new commands executed will be in a different scope, and by default set nocount off is always in effect. But as stated above in comments, it's considered a good practice, just to explicitly indicate that this setting will return to normal when the proc is finished executing.
When a stored procedure is created, the SET QUOTED_IDENTIFIER and SET ANSI_NULLS settings are captured and used for subsequent invocations of that stored procedure. When executed inside a stored procedure, the setting of SET QUOTED_IDENTIFIER is not changed. When SET ANSI_DEFAULTS is ON, QUOTED_IDENTIFIER is also ON.
The SET NOCOUNT ON stops the message indicating the number of rows affected by a Transact-SQL statement from being returned as part of the results. MySQL doesn't report the number of rows affected by a query, therefore there's no such function.
When ANSI_NULLS is ON, all comparisons against a null value evaluate to UNKNOWN. When SET ANSI_NULLS is OFF, comparisons of all data against a null value evaluate to TRUE if the data value is NULL. If SET ANSI_NULLS is not specified, the setting of the ANSI_NULLS option of the current database applies.
Ok now I've done my research, here is the deal:
In TDS protocol, SET NOCOUNT ON
only saves 9-bytes per query while the text "SET NOCOUNT ON" itself is a whopping 14 bytes. I used to think that 123 row(s) affected
was returned from server in plain text in a separate network packet but that's not the case. It's in fact a small structure called DONE_IN_PROC
embedded in the response. It's not a separate network packet so no roundtrips are wasted.
I think you can stick to default counting behavior almost always without worrying about the performance. There are some cases though, where calculating the number of rows beforehand would impact the performance, such as a forward-only cursor. In that case NOCOUNT might be a necessity. Other than that, there is absolutely no need to follow "use NOCOUNT wherever possible" motto.
Here is a very detailed analysis about insignificance of SET NOCOUNT
setting: http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount/
It took me a lot of digging to find real benchmark figures around NOCOUNT, so I figured I'd share a quick summary.
When SET NOCOUNT is ON, the count (indicating the number of rows affected by a Transact-SQL statement) is not returned. When SET NOCOUNT is OFF, the count is returned. It is used with any SELECT, INSERT, UPDATE, DELETE statement.
The setting of SET NOCOUNT is set at execute or run time and not at parse time.
SET NOCOUNT ON improves stored procedure (SP) performance.
Syntax: SET NOCOUNT { ON | OFF }
Example of SET NOCOUNT ON:
Example of SET NOCOUNT OFF:
I guess to some degree it's a DBA vs. developer issue.
As a dev mostly, I'd say don't use it unless you absolutely positively have to - because using it can break your ADO.NET code (as documented by Microsoft).
And I guess as a DBA, you'd be more on the other side - use it whenever possible unless you really must prevent it's usage.
Also, if your devs ever use the "RecordsAffected" being returned by ADO.NET's ExecuteNonQuery
method call, you're in trouble if everyone uses SET NOCOUNT ON
since in this case, ExecuteNonQuery will always return 0.
Also see Peter Bromberg's blog post and check out his position.
So it really boils down to who gets to set the standards :-)
Marc
If you're saying you might have different clients as well, there are problems with classic ADO if SET NOCOUNT is not set ON.
One I experience regularly: if a stored procedure executes a number of statements (and thus a number of "xxx rows affected" messages are returned), ADO seems not to handle this and throws the error "Cannot change the ActiveConnection property of a Recordset object which has a Command object as its source."
So I generally advocate setting it ON unless there's a really really good reason not to. you may have found the really really good reason which I need to go and read into more.
At the risk of making things more complicated, I encourage a slightly different rule to all those I see above:
NOCOUNT ON
at the top of a proc, before you do any work in the proc, but also always SET NOCOUNT OFF
again, before returning any recordsets from the stored proc. So "generally keep nocount on, except when you are actually returning a resultset". I don't know any ways that this can break any client code, it means client code never needs to know anything about the proc internals, and it isn't particularly onerous.
Regarding the triggers breaking NHibernate, I had that experience first-hand. Basically, when NH does an UPDATE it expects certain number of rows affected. By adding SET NOCOUNT ON to the triggers you get the number of rows back to what NH expected thereby fixing the issue. So yeah, I would definitely recommend turning it off for triggers if you use NH.
Regarding the usage in SPs, it's a matter of personal preference. I had always turned the row count off, but then again, there are no real strong arguments either way.
On a different note, you should really consider moving away from SP-based architecture, then you won't even have this question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With