Getting the ROWCOUNT value (not ##ROWCOUNT) in SQL - sql

Is there a way to see what ROWCOUNT is set to?
The component that is used to call my stored procedure has an option to limit how many rows are returned, but it apparently does that by setting ROWCOUNT. One stored procedure only returns a single aggregated row, but the intermediate queries sometimes return more than the limit and are getting truncated. The function that does all of this is generic and is used to call other stored procedures; some my other procedures may need the limit.
Right now I am setting ROWCOUNT to a very large number at the top of my stored procedure and then setting it back to the (hard-coded) regular limit before I return my result. I don't maintain the component that calls my stored procedures so I may not know if the returned row limit is changed. What I'd like to do is set a local variable to the current ROWCOUNT value, and then set it back at the end. Is there any way to actually see what ROWCOUNT is set to?

If you query the sys.dm_exec_sessions dmv it will return the number of rows returned on the session up to this point (should of course be the same as ##rowcount).
SELECT row_count FROM sys.dm_exec_sessions
WHERE session_id = ##spid
You might be able to play around with that to see if you can use it
Right now I am setting ROWCOUNT to a very large number at the top of my stored procedure
You can also just do SET ROWCOUNT 0, in this case it will return all rows

Stop using SET ROWCOUNT. It's being partially deprecated anyway.
Use TOP which has been there since SQL Server 2000: 11 years. This is per query and does not affect intermediate rows which means you can appyl it when needed, not globally as you are now.
Edit, Feb 2012
It's being removed in the next release after SQL Server 2012 too for insert, update and delete

Related

Stored procedures vs standard select update, avoid locks

In order to retrieve an ID, I first do a select and then an update, in two consequent queries.
The problem is that I am having problems with locked rows. I've read that putting both this statements, Select and Update in one stored procedure it helps with the locks. Is this true?
The queries I run are:
select counter
from dba.counter_list
where table_name = :TableName
update dba.counter_list
set counter = :NewCounter
where table_name = :TableName
The problem is that it can happen that multiple users are selecting the same row and also possible that they update the same row.
Assumptions:
you're using Sybase ASE
your select returns a single value for counter
you may want the old counter value for some purpose other than performing the update
Consider the following update statement which should eliminate any race conditions that may occur with multiple users running your select/update logic concurrently:
declare #counter int -- change to the appropriate datatype
update dba.counter_list
set #counter = counter, -- grab current value
counter = :NewCounter -- set to new value
where table_name = :TableName
select #counter -- send previous counter value to client
the update obtains an exclusive lock on the desired row (or page/table depending on table design and locking scheme)
with an exclusive lock in place you're able to retrieve the current value and set the new value with a single statement
Whether you submit the above via a SQL batch or a stored proc call is up to you and your DBA to decide ...
if statement cache is disabled, a SQL batch will need to be compiled each time it's submitted to the dataserver
if statement cache is enabled, and you submit this SQL batch on a regular basis then there's a chance the previous query plan is still in statement/procedure cache thus eliminating the (costly) compilation step
if a copy of previous stored proc (query) plan is not in procedure cache then you'll incur the (costly) compilation step when loading a (proc) query plan into procedure cahe
a stored proc is typically easier to replace in the event of a syntax/logic/performance issue (as opposed to editing, and possibly compiling, a front-end application)
... add your (least) favorite argument for SQL batch vs stored proc (vs prepared statement?) vs ??? ...
Is the table counter_list accessed by multiple clients concurrently ?
The best practices for OLTP is to call a stored procedure that will perform the update logic in one transaction.
Check that the table dba.counter_list has an index on column table_name.
Check also that it is row level locked.

How to count the number of result sets returned by a stored procedure? (SQL Server 2012)

Actually I have a Stored Procedure(which takes a object as input) which return either two or three table(Result sets). Now i have to categorized the objects by the no of result sets. How can i do it in programmatic way??
The procedure is non-editable. Otherwise it was a small job which was done by adding a flag.
Thanks in Advance
Create a dataset and fill it by calling the stored procedure. Then count the tables of the dataset.
Count the number of successful NextResult() calls to your SqlDataReader.
Update following the discussion in comments.
Result sets become available immediately. That means, the first one can become available long before stored procedure completion and as long as the procedure is running there is no way (apart from the source code analysis) to determine how many more result sets would still become available. So, you need to run the procedure to the end, get all the result sets and only then you would be able to count them properly. What you suggest is effectively running stored procedure on SQL Server to the end and analyzing there how many result sets became available. That can (sort of) be done through EXEC ... WITH RESULT SETS (SQL Server 2012 and on) with error handling but that's going to be drastically inefficient.
If you can create a new procedure why not re-implement the existing one with an extra return value?

Do I have to include "SELECT ##RowCount" if I have more than one SQL statement?

I know that, if I execute a single SQL statement that UPDATEs or DELETEs some data, that it will return the number of rows affected.
But if I have multiple SQL statements in a sql script, and I want to know the number of rows affected from the last statement executed, will it still return that automatically, or do I need a
SELECT ##RowCount
at the end of the script?
The code in question is not a Stored Procedure. Rather, it is a parameterized SQL script stored in an arbitrary location, executed using the ExecuteStoreCommand function in Entity Framework, as in:
var numberOfRowsAffected = context.ExecuteStoreCommand<int>(mySqlScript, parameters);
It depends on the NOCOUNT setting when executing your quer(y/ies).
If NOCOUNT is ON then no DONE_IN_PROC messages will NOT be returned.
If NOCOUNT is OFF, the default setting, then DONE_IN_PROC messages will be returned, (eg. counts).
Both of these situations are different to executing,
SELECT ##ROWCOUNT;
which will return a result set with a single scalar value, different from a DONE_IN_PROC message. This will occur, regardless of the setting of NOCOUNT.
I believe that SELECT ##ROWCOUNT is sometimes used to make Entity Framework "play" with more complex TSQL statements because EF both requires
Requires a count for post validation
And will accept a scalar number result set as a substitute for a DONE_IN_PROC message.
Its important that SELECT ##ROWCOUNT; is executed immediately after the last query statement because many statements will reset ##ROWCOUNT and therefore yield an unexpected result.
Just to be specific on answer part, you would need to add SELECT ##RowCount to return number of rows affected by last statement.
I think confusion might be due to rows returned in SSMS window while executing query.By default SSMS shows number of rows returned for all sql statements but it returns affected rows as message not a dataset.
##ROWCOUNT will automatically return number of rows effected by the last statement.
Please find the msdn link here
https://msdn.microsoft.com/en-us/library/ms187316.aspx

Count number of rows edited by Stored Proc

We have a stored procedure in a MSSQL Server 2008 database that performs a number of reads and writes in response to user action on a website.
I would like to know if there is any way of counting how many rows were edited/created during the procedure, preferably without having to alter the proc (although alterations are possible).
Does anyone have any suggestions? I looked at ##ROWCOUNT but that covers reads and writes (and I'd prefer not o go throught the proc and manually add up ROWCOUNT after each UPDATE)
EDIT: the proc is being called from C# using the System.Data.SqlClient classes
Without editing the proc, your best bet would be to start a SQL Server Profiler session, track SP:StmtCompleted, filter ObjectName to your proc, and filter TextData to the statements you want to monitor. Be sure to include the RowCount column.
Note that you can't get the row counts from the extended events sql_statement_completed event. There is no row count column; just duration, CPU, reads and writes.
If you can edit the proc, you would have total control over the behavior. You could sum up the ##ROWCOUNT of every INSERT/UPDATE/DELETE operation. This count could be returned as an output parameter, written to the log, PRINTed, traced with user-defined trace events, saved to a table, etc.
MS Sql Profiler is where you want to start for something like this.
##ROWCOUNT will give you counts based on the last run statement, so with that you could create a local variable and update it after everytime with ##ROWCOUNT
Otherwise you will have to get into Profiler and watch from there, but that is not a sustainable solution, better suited for troubleshooting.
I Have no idea about MySQL, But Oracle SQL provides a variable called SQL%ROWCOUNT, which contains the number of rows effected in the immediately previous transaction

How does updating or inserting while looping through a result set affect the result set itself?

suppose I fetch an RS, based on certain conditions and start looping though it , then , on certain situations , I update insert or delete records, which may have been part of this RS, using separate prepared statements.
How does this effect the result set ? My inclination is to think that since the Statement which fetched this RS was executed earlier in the process, this RS will now be blind to the changes made by my prepared statements.
Pseudocode :
Preapare Statement ps1
execute ps1 -> get Result Set rs1
loop through rs1
{
Update or delete records using other prepared statements
}
Read Consistency
Oracle guarantees that the set of data seen by a statement is consistent with respect to a single point in time and does not change during statement execution (statement-level read consistency)
That is why, If you have a query such as
insert into t
select * from t;
Oracle will simply duplicate all rows without going into an infinite loop or raising an error.
There are other implications because of this.
1) Oracle reads from the rollback segment to provide you with this read-consistent image of your data. So, if your rollback segments are nor correctly sized, or you commit across fetches, you'll get the "Snapshot too old" error, since your rollback data is no longer available.
Ok , so if that is the case , is it possible to refresh it while making updates ? I mean aside from making the cursor updateable and using the inbuilt functions of the result set.
2) Each query sees the data at the point of time it began. If by refresh you mean refiring the query, then the data you see might be different again, if you do commits in your pl/sql body or within a pl/sql loop or if some other transactions are running in your system concurrently.
It doesn't. The result set of a query/cursor is kept by the database, even if you alter or remove the rows that are the base of this result set. So you are correct, it is blind to changes made after the statement is executed.