Catch/Work with/Handle multiple datasets in a Stored Procedure from another Stored Procedure - sql

Is it possible to work with the returned datasets from a stored procedure? Basically I have a stored procedure (lets call it SP_1) and it calls another stored procedure (lets call it SP_2). SP_2 has 5 or so select statements. What I want to do is handle each select statement within SP_1. Basically to manipulate the data or whatever, but I do not know how to get it.
Let me show what im doing and that may make things clearer
CREATE PROCEDURE [dbo].[usp_1]
AS
exec usp_2
//How do I store the multiple select statements results in this stored proc?

In order to work, all the SELECTs within SP_2 will need to return the same number of compatible columns. If one returns 2 columns, another returns 5, and another returns 10, then it won't work.
If each SELECT does return the same number of columns, and the datatypes are consistent then you should be good to go using this approach in SP_1
CREATE TABLE #test (Col1 VARCHAR(10), Col2 VARCHAR(10))
INSERT #test
EXECUTE SP2 -- all resultsets return 2 VARCHAR columns
-- Now use #test which should contain all the combined results from SP2
However, if they all return different columns then you can't do it. You'd need to break each individual select into it's own sproc and call each one independently. SP2 would change to call those sub sprocs too.

Related

Is it possible to retrieve Selected Columns from Stored Procedure?

I have a stored procedure which returns a few columns from a SELECT. Now I need to grab 2 columns out of those columns in my new stored procedure and use them.. I am trying to do this using EXEC method. Is it possible to do this?
Ex : Original stored procedure:
CREATE PROCEDURE myBaseProcedure
#stId INT
AS
BEGIN
SELECT Name,
Address,
StudentId,
Grade
FROM Student
WHERE StudentId = #stId
END
New stored procedure:
CREATE PROCEDURE myNextProcedure
BEGIN
EXEC myBaseProcedure 19 -- Here I need to grab only StudentId and Name??
END
Given that you cannot dump to a temp table or table variable since the base stored procedure might sometimes add columns, there are three approaches that would do this:
You can effectively SELECT from a stored procedure using either OPENROWSET or OPENQUERY
You can use SQLCLR to create a table-valued function that executes the procedure, returns a struct of just the fields that you want, which will be the only fields that you read or "get" from the SqlDataReader.
You can use SQLCLR to create a stored procedure that executes the procedure to get a SqlDataReader, and instead of returning the SqlDataReader to SqlContext.Pipe.Send(), you would use SendResultsStart, SendResultsRow, and SendResultsEnd. You would create a SqlDataRecord of just the fields you wanted, and those would also be the only fields that you read or "get" from the SqlDataReader. While this still leaves you with a stored procedure, the filtering of the fields is done within the CLR-based proc so the output is guaranteed to be just the fields you want, regardless of how the result set structure of the base stored procedure changes. In this way you could create a local temp table to dump the results to, which would be better for JOINing to other tables. This method also allows for you to pass in a list of fields to the CLR-based stored procedure that would be parsed and used as the fields to dynamically construct the SqlDataRecord with as well as to dynamically determine which fields to get from the SqlDataReader. That would be a little more complicated but also quite a bit more flexible :).
You don't need to create a new stored procedure for this, you can integrate the stored proc call in a simple query using OpenQuery or use a temporary table.
Using OPENQUERY
SELECT Name,
Address
FROM OPENQUERY(ServerName, 'EXEC myBaseProcedure 19')
-- WHERE your_field = expected_value --> if you need to add filters
Using Temp table
Declare #MyTempTable Table (columns definitions)
Insert #MyTempTable Exec myBaseProcedure 19
Select Name,
Address
FROM #MyTempTable

Single variable consists of number of characters in stored procedure?

CREATE PROCEDURE Testing1
#Varaible nvarchar(50),
#value integer
AS
BEGIN
DECLARE #SUMM FLOAT
SET #SUMM=(#value*2.38/7.456)*2
PRINT #Varaible
PRINT 'EXPENSES IS'
PRINT #SUMM
END
Output is:
PETER
EXPENSES IS
24.2597
The above is my code where I am passing a single input parameter.
If I want to pass multiple values like peter,robber,licoln,mat
#varaible peter,robber,licoln,mat
#value 37 45 66 77
is it possible in SQL??
If you're only sending a few values in your delimited strings, I would suggest simply using the proper datatypes and calling the stored procedure a few times with individual values.
If, however, your delimited strings might contain hundreds or thousands of discrete values, then calling a proc that many times could be costly in terms of performance, especially if you can't send them all in one batch (I'm sure you want to use parameters rather than a giant concatenated command). If this is the case, you have a few options:
Use Table Valued Parameters. This is like passing arrays as arguments to your proc.
Pass XML to your proc, then shred and process it within the procedure.
Insert your data to staging/temp tables, then call the procedure to operate on those tables.
Take a step back and see if it makes sense to do more processing in your app. DB code usually doesn't scale nearly as well as app code.
Send these delimited strings to your proc, split/parse them, then loop over the results in SQL. This seems to be what you're asking about and is possibly the least elegant option, even though it's one of the more popular ways to abuse a relational database.
The table valued parameters approach seems very 'approachable', but is only available as of MSSQL 2008. If you are still stuck with MSSQL 2005 then, maybe, the temporary table approach works best for you?
Your code could look something like:
-- define your stored procedure
CREATE PROC sptest1 AS
BEGIN
-- do some stuff with #tmp, like join it to other tables
-- and UPDATE values in these tables with it!
-- or simply list a processed version of #tmp:
SELECT nam,val*(2.38/7.456)*2 FROM #tmp
END
-- prepare input values by creating a temporary table on the fly
SELECT 'Peter' nam,23 val INTO #tmp
UNION ALL SELECT 'Paul',27
UNION ALL SELECT 'Harry',16
UNION ALL SELECT 'Mary-Ann',45;
-- and call the procedure:
EXEC sptest1
So, your frontend will have to build the SELECT ... INTO #tmp ... string. After that the rest of the processing can be done inside your stored procedure.

SQL - Need to run stored proc with ~100 different params, what's the best way to do this?

Assuming I have a table with one field called ID that stores 100 different integer values. I can select all of these rows simply by doing select id from example_table
I then have a stored procedure that I need to execute for each of these id's (as the sole parameter) and then select specific columns from (the stored procedure returns more data then I need). Besides executing the stored procedure 100 separate times into a temporary table and then selecting data from this table - how else could I do this?
You can pass table parameter to the procedure.
Check http://www.techrepublic.com/blog/datacenter/passing-table-valued-parameters-in-sql-server-2008/168
Update
CREATE TYPE LIST_OF_ID TABLE (ID INT);
go
CREATE PROCEDURE PROC1(#ids LIST_OF_ID READONLY)
....

How can a stored procedure return ROWCOUNT?

I have written stored procedure which has 2 Insert queries and 1 Update query inside it. Of all these,either insert queries or update query are executed at a time. Now my problem is to get ROWCOUNT in each case. Say suppose if insert operations are executed,then I want stored procedure to return ##ROWCOUNT to the calling application, so that the application will be aware of whether the required operations executed correctly or not. Can anyone suggest/tell me how can I get the rows affected from the stored procedure?
Use Output parameters in your stored procedures to return the RowCount of your inserts / updates.
Refer MSDN link for more information on how to use Output params
You can have multiple output params so you can have 2 different output params one each for your insert and the 3rd for your update statement.
Example:
CREATE PROCEDURE GetEmployeeData
#employeeID INT,
#managerID INT **OUTPUT**
AS
BEGIN
....
....
Additionally, you can always concatenate the rowcounts of your 2 Inserts / Update using delimiters and return them as one value eg: "10;0" - However that is the old fashioned and "I would not recommend" approach.
Also, you could create a table variable and return the table with rows = number of Inserts / updates and the value of the column = RowCount affected.

Stored Procedure returning Multiple resultset

One Stored procedure returning multiple result sets and I need only the last result set, How do I achieve this without changing original procedure. am using the last reulst set in further processing in other Stored procedure.
if you are "filling" a dataset in c#, very simple, just use:
datasetobj.Tables[datasetobj.Tables.Count-1].Table
to get the DataTable
if doing this within sql procedures (i.e. one procedure calling another that returns multiple), best solution would be to use output variables. concept:
procedure1 returns multiple resultsets
when calling:
declare #table1 table (), #table2 table ()
exec procedure1 out #table1, out #table2