There was a question I answered the other day where someone complained that the rowcount was always 0. Below is a simplified version of the query, can you tell why @SomeCount will be 0?
declare @SomeCount int
select 1
union all
select 2
print '1'
select @SomeCount = @@rowcount
select @SomeCount
The value that the @SomeCount parameter returns will be 0 because print resets the value of @@ROWCOUNT to 0
Let’s take a look at another example, but instead of using print we will use a SET @param = value statement. Can you guess what @SomeCount will return in the select statement?
DECLARE @SomeCount INT
SELECT 1
UNION all
SELECT 2
SET @SomeCount = 0
SELECT @SomeCount = @@ROWCOUNT
SELECT @SomeCount
The value that the @SomeCount parameter returns will be 1 because the SET @param = value always sets the @@ROWCOUNT value to 1. Here is what Books On Line has on statements that make a simple assignment
Statements that make a simple assignment always set the @@ROWCOUNT value to 1. No rows are sent to the client. Examples of these statements are: SET @local_variable, RETURN, READTEXT, and select without query statements such as SELECT GETDATE() or SELECT ‘Generic Text’.
Let’s look at another example, what do you think will be returned in the query below
DECLARE @SomeCount INT, @SomeOtherCount int
SELECT @SomeOtherCount = number
FROM master..spt_values
SELECT @SomeCount = @@ROWCOUNT
SELECT @SomeCount
On my machine it returns the value 2506, this is because SQL Server reads all the rows from the master..spt_values table
Books On Line explanation on that one is the following
Statements that make an assignment in a query or use RETURN in a query set the @@ROWCOUNT value to the number of rows affected or read by the query, for example: SELECT @local_variable = c1 FROM t1.
Let’s take a look at another rather silly example
DECLARE @SomeCount INT
SELECT 1
UNION all
SELECT 2
if 1=1
SELECT @SomeCount = @@ROWCOUNT
SELECT @SomeCount
As you can see the IF statement also resets the @@ROWCOUNT and you get back 0
So when should you store @@ROWCOUNT into a variable?
If you want to store the rows that were affected by A DML statement then you need to grab @@ROWCOUNT immediately after the DML statement. There can’t be any code between the DML statement and your code that stores @@ROWCOUNT into a variable.
So instead of this
declare @SomeCount int
select 1
union all
select 2
print '1'
select @SomeCount = @@rowcount
select @SomeCount
You do this, move the print until after you populate your variable with the @@ROWCOUNT value
declare @SomeCount int
select 1
union all
select 2
-- no other code beyween the DML statement and populating @SomeCount
-- with the @@rowcount value
select @SomeCount = @@rowcount
print '1'
select @SomeCount
To learn more about @@ROWCOUNT visit Books On Line: http://msdn.microsoft.com/en-us/library/ms187316.aspx
What about @@error
I am just giving you a little more code here, the same also applies for @@ERROR, so if you have code that needs to store both @@ERROR and @@ROWCOUNT then do it in one assignment.
There are 3 versions of the same query below, all of them will terminate with an error.
First let’s look at code that first grabs the rowcount and then the error
declare @SomeCount int, @Error int
select 1
union all
select 2/0
select @SomeCount = @@rowcount
select @Error = @@error
select @SomeCount as TheRowcount, @Error as TheErrorCount
TheRowcount TheErrorCount 0 0
As you can see both variables are 0, TheRowcount is 0 because the query terminated and no rows were returned, TheErrorCount is 0 because the statement that assigned @SomeCount was successful
Here is another example, all we did was reversed the assignment of @SomeCount and @Error
declare @SomeCount int, @Error int
select 1
union all
select 2/0
select @Error = @@error
select @SomeCount = @@rowcount
select @SomeCount as TheRowcount, @Error as TheErrorCount
TheRowcount TheErrorCount 1 8134
In this case TheRowcount is 1 because the statement that assigned @Error reset @@ROWCOUNT to 0
Finally we will look at what happens when you assign both variables with one statement
declare @SomeCount int, @Error int
select 1
union all
select 2/0
select @Error = @@error, @SomeCount = @@rowcount
select @SomeCount as TheRowcount, @Error as TheErrorCount
TheRowcount TheErrorCount 0 8134
This is correct, TheErrorCount returns the error number and TheRowcount returns 0 because the query blew up
To learn more about @@ERROR visit Books On Line here: http://msdn.microsoft.com/en-us/library/ms188790.aspx
*** Remember, if you have a SQL related question, try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum