Stored Procedure returning Multiple resultset - sql

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

Related

Execute stored procedure in a loop for set of records

I want to write a stored procedure to loop through set of records and for each of the record execute another stored procedure.
Select query returning list of id's:
select id
from abc
where some condition
I have a stored procedure usp_get_data #id=id which I want to execute for each of the rows of the select query. I do not want to use cursor. What are the other ways I can achieve this?
foreach(item in select statement)
{
execute stored procedure
}
The sub stored procedure will return a list of records which I will then return back from the main stored procedure
I do not want to use cursor. What are the other ways I can achieve this?
Rewirte the stored procedure to operate over a set of data. You can pass bulk data to a stored procedure using a table-valued parameter, or by loading data into a Temp table, which the stored procedure then uses.
Or use a cursor. They aren't the worst thing, and "calling a stored procedure for each row" is probably the most common legitimate use of a cursor. Also the looping-without-a-cursor solutions are all dumb and worse than using a cursor.

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

Insert SQL stored procedure values into another stored procedure

I have a large stored procedure that returns a record for a person, there are four fields that I need to return very specific values for. I have another stored procedure that performs this specific action.
The small stored procedure is as follows:
SELECT TOP 1
wea.field,
wea.degree,
wea.degreeyear,
wpp.ProgramCategory
FROM dbo.webeventaffiliation wea
LEFT JOIN dbo.WebProgramParticipants wpp
ON
wea.userid = wpp.UserID AND
wea.eventid = wpp.eventid
INNER JOIN dbo.WebProgramCategoryDescriptions wpcd
ON
wpcd.ProgramCategory = wpp.ProgramCategory
WHERE wea.UserID = #UserID
ORDER BY wea.datelastmodified DESC
LARGE STORED PROCEDURE SAMPLE RETURN DATA:
Name: XXXXX
Address: XXXXX
Field: [small stored procedure value]
Degree: [small stored procedure value]
DegreeYear: [small stored procedure value]
ProgramCategory: [small stored procedure value]
My question is how do I get the 4 data items from this stored procedure into their respective columns within the dataset that is returned from the large stored procedure?
Using a table-valued function instead of a stored procedure could be helpful. You will be able to use the TVF just like a table ie:
SELECT
COLUMNS_NAMES
FROM
TVF(PARAMS)
As your small stored procedure doesn't write anything, you could just write it as a table valued function.
You can then apply the function to an entire data-set by using APPLY.
(Table valued functions that are written INLINE (not multi-statement) are then explanded macro-like to execute extremely efficiently. This is perfect for your description as the function would just be a single SELECT statement already.)
The Function:
CREATE FUNCTION dbo.your_function(#user_id AS INT)
RETURNS TABLE
AS
RETURN
<your query>
The function used in a query inside your big SP:
SELECT
...,
user_detail.field,
user_detail.degree,
user_detail.degreeyear,
user_detail.programcategory
FROM
...
CROSS APPLY
dbo.your_function(some_table.user_id) AS user_detail
In general I use functions to encapsulate queries, and only wrap them up in Stored Procedures if...
1) I need to write data. (Functions can't INSERT, UPDATE or DELETE)
2) I want to create an API like interface to client applications.
Since you're getting only one row with four values you could use OUTPUT parameters:
EXECUTE SomeSmallerProcedure
#field OUTPUT, #degree OUTPUT, #degreeyear OUTPUT, #ProgramCategory OUTPUT;
Your procedure listed above would change to:
ALTER PROCEDURE SomeSmallerProcedure
#field varchar(255) OUTPUT,
#degree varchar(255) OUTPUT,
#degreeyear varchar(255) OUTPUT,
#ProgramCategory varchar(255) OUTPUT
AS BEGIN SET NOCOUNT ON;
SELECT TOP 1
#field = wea.field,
#degree = wea.degree,
#degreeyear = wea.degreeyear,
#ProgramCategory = wpp.ProgramCategory
-- ... rest as before
The signature of your procedure above would have to include those parameters explicitly for OUTPUT.

Insert into table from stored proc

I am trying to use a stored procedure that contains two different cursors as table input like such:
INSERT INTO table1 EXEC * FROM tblDailySales
The stored proc contains two cursors - I did not run just using.
I get the following error:
A cursor with the name 'csrDistricts' does not exist.
I also, get this error
An INSERT EXEC statement cannot be nested
The stored proc contains no EXEC that I can see.
What kind of stored proc other than simple SELECT can be used as source for table?
Is table1 already defined? If so all you should have to do is
INSERT INTO table1
EXEC storedProcedureName
Now, the trick is, the stored procedure will only be able to return one result set and insert into the table.
If you need to insert two different result sets, you'll have to gather then in two different stored procedures, then run two INSERT statements.
If you must do them at once, you'll need to do the insert from within the stored procedure.

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

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.