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

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?

Related

Stored procedure (Input vs Output) vs Return - SQL Server

I am new to SQL Server and I recently studied about stored procedures.
I want to know when should you use an input or an output stored procedure and how is it different from return. Also when do you prefer to use return over stored procedures.
I am unable to find the specific answer a layman's guide would be really thankful.
I only know
When you want to return one or more items with a data type then it is better to use an output parameter.
Generally, use an output parameter for anything that needs to be returned.
When you want to return only one item with only an integer data type then it is better to use a return value.
Generally, the return value is only to inform success or failure of the stored procedure.
A return List item a value of 0 indicates success and any non-zero value indicates failure.
It's quite simple, actually:
Use input parameters to send data into the stored procedure.
Use Output parameters to return scalar values from the stored procedure.
Use a Select statement inside the procedure to return tabular data.
Don't use Return.1 If you want to abort a stored procedure mid-process, throw an error instead.
1 Well, it depends on the client, but usually, it's simpler to use errors than return codes, and also safer. There is no guarantee that the client will actually bother to check the return code, but if you throw an error, that can't be ignored.
However, there are probably a few times when it's better to return a number other than zero to indicate failure, but that means that whatever code that is using the procedure must be aware of the meaning of the numbers, which often leads to a terrible mess.
I once worked for a company that used this kind of thing, and I inherited a c# code containing an enum of approximately 300 members, all for error codes thrown from stored procedures - which means that every new error in any stored procedure we had to first make sure that error is not already in the enum, and if it's not, we had to recompile the c# code and re-deploy it even if we only changed an existing procedure.
Naturally, this was a maintenance nightmare.

Stored Procedure - General

With a stored procedure in a database, would the following situation be true?
I have a procedure that queries a very large table, and in my query I call the stored procedure, and follow it with a WHERE record_class = "THE ONE IM LOOKING FOR".
In the stored procedure I'm not limiting the records by the record_class, so does the WHERE clause do anything other than filter the results that the procedure returns?
In other words, if I wanted to speed up the results because it takes too long, would adding a parameter for the record_class to the procedure and selecting only those when it performs its tasks be quicker than using the WHERE clause?
Your analysis is completely true, if you apply the condition directly in your stored procedure instead of outside it will for sure be more performant.
In the first situation, your procedure will return every rows without applying your condition (this condition is completely unknown for the procedure) and this result will then be filtered with your WHERE clause.
Depending on your needs, the best solution may be to define a parameter for your stored procedure so you can pass this parameter at execution and the result will be filtered. I don't know exactly what is the purpose of your procedure but by doing so, you'll keep the possibility to execute the same procedure for multiple situations (you simply need to pass the record_class you want to filter the result or let it NULL if you want the entire data).
This approach requires a little modification to your procedure (adding a parameter) and a modification of your query (adding the WHERE clause that filters the result if needed).
Hope this will help you.

What does "query" mean in SQL Server in "use query governor"

If I am executing a stored procedure containing a number of successive query statements,
Does use query governor apply to each statement executed in the stored procedure, or does it mean a single executed statement - in this case the entire stored procedure?
I think you are mixing up some concepts.
The first concept is what is a transaction? That depends if you are using explicit or implicit transactions.
By default, implicit transactions are set on.
If you want to have all the statements either committ or rollback in a stored procedure, you will have to use BEGIN TRANS, COMMIT and/or ROLLBACK statements with error checking in the stored procedure.
Now lets talk about the second concept. The resource governor is used to limit the amount of resources given to a particular user group.
Basically, a login id is mapped by a classifier function to a workload group and resource pool. This allows you to put all your users in a low priority group giving them only a small slice of the CPU and MEMORY while your production jobs can be in a high priority group with the LION's share of the resources.
This prevents a typical user from writing a report that has a huge CROSS JOIN and causes a performance issue on the production database.
I hope this clears up the confusion. If not, please ask exactly what you are looking for.
It appears the answer to my question is that a stored procedure counts as a query in this context;
We have spent some time examining an issue with a stored procedure comprising a number of EXEC'd dml statements, which timed out with "Use Query Governor" selected, according to the value of the number of seconds applicable. Deselecting "Use Query Governor" resolved the problem.

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

Creating entities from stored procedures which have dynamic sql

I have a stored procedure which uses a couple of tables and creates a cross-tab result set. For creating the cross-tab result set I am using CASE statements which are dynamically generated on basis of records in a table.
Is it possible to generate an entity from this SP using ADO.NET Entity framework? Cuz each time I try Get Column Information for the particular SP, it says that The selected stored procedure returns no columns.
Any help would be appreciated.
A member of my team recently encountered something like this, where a stored procedure was generating all kinds of dynamic SQL and returning calculated columns so the data context didn't know what to make of it. I haven't tried it myself yet, but this was the solution he claimed worked:
The solution is simply to put the line
“SET FMTONLY OFF;” into the proc.
This allows the Data Context to
actually generate the return class.
This works in this case, only because
the proc is doing nothing but querying
data.
Full details here:
http://tonesdotnetblog.wordpress.com/2010/06/02/solution-my-generated-linq-to-sql-stored-procedure-returns-an-int-when-it-should-return-a-table/
You only need the “SET FMTONLY OFF” in
the proc long enough to generate the
class. You can then comment it out.