SET NOCOUNT ON brings back messages in SQL Server Management Studio - sql-server

I have the following stored procedure:
ALTER PROCEDURE [dbo].[spTitle_GetTitleById]
(
#TitleId INT
)
AS
BEGIN
SET NOCOUNT ON;
SELECT
Id,
Name,
Active
FROM
Title
WHERE
Id = #TitleId
END
I was told to use SET NOCOUNT ON; if I don't want messages to be returned. I ran this stored procedure through SQL Server Management Studio 2008 and I got the following message:
(1 row(s) affected)
This is still a message. One of our DBAs said that this will be the case, but when it is run through an application it will not return any messages. Is there a way that I can test to see if messages were returned or not when I use SET NOCOUNT ON; I don't want to assume, I want to know.
I right clicked the stored procedure and selected Execute Stored Procedure... I then set it to OFF, and I got:
(1 row(s) affected)
(1 row(s) affected)
So setting it to ON or OFF it still brought back messages in the Messages tab in the results panel.
Just another question, when will it be wise (in what scenarios) to use SET NOCOUNT OFF;?

SET NOCOUNT ON is reset when the procedure exits and it goes up the call stack. When you execute the procedure from SSMS it generates a script like the following.
DECLARE #return_value int
EXEC #return_value = [dbo].[spTitle_GetTitleById]
#TitleId = 1
SELECT 'Return Value' = #return_value /*Message comes from here*/
If youi wanted to avoid that for some reason you would need to SET NOCOUNT ON in the outer batch. See SET NOCOUNT ON usage for some discussion about the merits of having this ON or OFF

Just another question, when will it be wise (in what scenarios) to use SET NOCOUNT OFF?
See What are the advantages and disadvantages of turning NOCOUNT off in SQL Server queries? For the benefits turning SET NOCOUNT ON
As for why you would want to turn this off (so that rowcounts are returned) - you need this off whenever you want to be able to tell how many rows were affected in situations where there is no resultset, or you wish to be able to get a rowcount without first reading through the entire resultset.
For example in .Net the DataAdapter class uses rowcounts and so setting NOCOUNT ON causes issues when editing or deleting data (source).

That is not correct, script out the proc an make sure it is not OFF instead o ON, if it is ON it should not return (1 row(s) affected) messages
Also how are you executing the proc
is is just this
exec spTitle_GetTitleById 1

Related

Why do we use the SET NOCOUNT ON; along with the SELECT ##ROWCOUNT;?

I am learning through the EF Core through the tutorials over here and I come across the following statements being used in the examples of the T-SQL queries:
1 SET NOCOUNT ON; Meaning (from here):
Stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set.
2 SELECT ##ROWCOUNT; Meaning (from here)
Returns the number of rows affected by the last statement.
The 1 and 2 are used simultaneously. And that is confusing for me. For instance, here:
exec sp_executesql N'SET NOCOUNT ON;
UPDATE [Books] SET [AuthorId] = #p0
WHERE [BookId] = #p1;
SELECT ##ROWCOUNT;
',N'#p1 int,#p0 int',#p1=4,#p0=1
I can not understand why would someone want to turn off the effect of the 2 with the help of 1 if it is possible to avoid the effect of the 2 by just not adding it into the query. I.e. the following query will do exactly the same as the above one:
exec sp_executesql N'UPDATE [Books] SET [AuthorId] = #p0
WHERE [BookId] = #p1;
',N'#p1 int,#p0 int',#p1=4,#p0=1
Am I missing something here or what is the purpose of using both the SET NOCOUNT ON and the SELECT ##ROWCOUNT simultaneously?
SET NOCOUNT ON stops the results from being printed on the console (screen).
The use of ##ROWCOUNT captures the row count as a parameter in T-SQL and makes it possible to use it for further processing. For instance, you could have conditional logic to do something if no rows are updated.
SET NOCOUNT is often used is suppress the DONE_IN_PROC TDS protocol messages (row counts) SQL Server would otherwise return to the client over the underlying TDS protocol stream. These messages can cause issues when using some SQL Server APIs unless the application is specifically coded to handle them (e.g. by invoking ADODB.Recordset.NextRecordSet) to ensure subsequent statements in the batch are executed and result sets returned. Consequently, use of SET NOCOUNT ON has become a common practice with SQL Server unless the row counts are actually needed by the application.
An additional benefit, called out in the doc reference in your question, is a performance benefit in cases where the batch contains many SQL statements. SET NOCOUNT eliminates the overhead of returning the messages that would be discarded anyway.

Is there a way to make SQL Server stored procedures automatically exit on error?

Consider the following stored procedure:
CREATE PROCEDURE [dbo].[TestError]
#Input int
AS
BEGIN
DECLARE #Test int = 1 / 0;
INSERT TestTable (Number)
VALUES (#Input);
END
And calling it:
EXEC TestError 123;
When I execute this stored procedure, the TestTable table still gets populated, despite the divide by zero error.
Can stored procedures be set to automatically exit on error, so that subsequent statements don't get executed?
add set xact_abort on; to the beginning of your procedures.
create procedure [dbo].[TestError] #Input int as
begin
set xact_abort, nocount on;
declare #Test int = 1 / 0;
insert TestTable (Number) values (#Input);
end
Why you should always include set xact_abort, nocount on; - Erland Sommarskog
This turns on two session options that are off by default for legacy reasons, but experience has proven that best practice is to always have them on. The default behaviour in SQL Server when there is no surrounding TRY-CATCH is that some errors abort execution and roll back any open transaction, whereas with other errors execution continues on the next statement. When you activate XACT_ABORT ON, almost all errors have the same effect: any open transaction is rolled back and execution is aborted. There are a few exceptions of which the most prominent is the RAISERROR statement. - Erland Sommarskog

CREATE PROCEDURE statement results in (1 row(s) affected)

I'm running SQL Server 2012.
I have a create procedure statement:
USE [dbname]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Test]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Test]
AS
SELECT 1
When I run this with dbname equals one database, I get:
(1 row(s) affected)
When running it dbname equals another database on the same server, I get:
Command(s) completed successfully.
Obviously this is a database setting or something specific to the database, but I can't seem to find anything. Does anyone know what is causing the difference?
Thanks in advance.
This may be cause of DDL trigger existence. as you mentioned in your comments, one of the triggers has SET NO COUNT ON, which will be stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set. if you comment it, or add it to the other trigger too, you will see the same results for both above mentioned scenarios.

read DONE_IN_PROC

If I understand correctly, with stored procedure result is also returned a message called DONE_IN_PROC
Fragment From MSDN:
... SET NOCOUNT ON eliminates the sending of DONE_IN_PROC messages to the
client for each statement in a stored procedure.
Is there a way to access this message somehow in Management Studio after executing stored procedure and read i.e. number of rows affected.
(I am asking out of curiosity and I know there are other ways to get number of rows affected)
Certain (if not all) Database APIs make the TDS layer's DONE_IN_PROC message accessible. If ODBC is the chosen Database API, see the http://technet.microsoft.com/en-us/library/ms130812.aspx discussion about SQLRowCount, SQLGetStmtAttr, and NOCOUNT.
Late to the party but are you just after the int from the message?
create proc delme as
begin
select * from sys.databases
end
go
set nocount on
go
exec delme --returns "(7 row(s) affected)" on the message channel
select ##ROWCOUNT --returns 7

Stored Procedure with update statement not functioning

I have created a very simple stored procedure and verified that the query that needs to be executed is a correct/running query. Yet, once stored in the SP, it does not do anything apart from returning '0':
USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GenerateVolume]
AS
BEGIN
SET NOCOUNT ON;
UPDATE test.dbo.[c500 CP_Simulation]
set GeneratedVolume = AvgFillRatePerDayPerCP +[dbo].[fn_InvsNorm](RAND(convert(varbinary, newid()))) * StDevFillRatePerDayPerCP
where test.dbo.[c500 CP_Simulation].OrgVPnr = test.dbo.[c500 CP_Simulation].OrgVPnr
END
No errors are given... Please give me a tip :)
When you use the
SET NOCOUNT ON
It will suppress the "xx rows affected" message.
If your query works fine, your rows are getting updated.
Since you have told sql server not to count how many rows were updated, you will not be told how many rows got updated.
Hope that clears some doubt.

Resources