views:

13004

answers:

11

I'm using SQL Server 2005, and I would like to know how to access different result sets from within transact-sql. The following stored procedure returns two result sets, how do I access them from, for example, another stored procedure?

CREATE PROCEDURE getOrder (@orderId as numeric) AS
BEGIN   
    select order_address, order_number from order_table where order_id = @orderId
    select item, number_of_items, cost from order_line where order_id = @orderId
END

I need to be able to iterate through both result sets individually.

Thanks in advance.

A: 

You could select them into temp tables or write table valued functions to return result sets. Are asking how to iterate through the result sets?

Kilhoffer
A: 

This doesn't make sense to me. If you need a result set you select it, why nest it in a stored proc ?

Perhaps you want a view or to use table variables. Can you be a bit more specific about why you need to access data in this fashion?

HollyStyles
A: 

There are two ways to do this easily. Either stick the results in a temp table and then reference the temp table from your sproc. The other alternative is to put the results into an XML variable that is used as an OUTPUT variable.

There are, however, pros and cons to both of these options. With a temporary table, you'll need to add code to the script that creates the calling procedure to create the temporary table before modifying the procedure. Also, you should clean up the temp table at the end of the procedure.

With the XML, it can be memory intensive and slow.

Josef
A: 

Put simply, in order to test them. I have a set of stored procedures which are used from a VB.NET client, which return multiple result sets. These are not going to be changed to a table valued function, I can't in fact change the procedures at all.

The result sets returned by the procedures are not the same data types or number of columns.

MatthieuF
A: 

So, then, are you asking how to iterate the result sets from the calling end? I'm still not clear on what you're asking. To return multiple result sets, you simply create two select statements.

Kilhoffer
+10  A: 

The short answer is: you can't do it.

From T-SQL there is no way to access multiple results of a nested stored procedure call, without changing the stored procedure as others have suggested.

To be complete, if the procedure were returning a single result, you could insert it into a temp table or table variable with the following syntax:

INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...

You can use the same syntax for a procedure that returns multiple results, but it will only process the first result, the rest will be discarded.

Brannon
I've just tested Brannon's solution, and in fact, if all of the queries within the called stored procedure return the same number of columns and data types, the result set returned will consist of a union of the result sets. Which is pretty much useless.Thanks for your help.
MatthieuF
A: 

Note that there's an extra, undocumented limitation to the INSERT INTO ... EXEC statement: it cannot be nested. That is, the stored proc that the EXEC calls (or any that it calls in turn) cannot itself do an INSERT INTO ... EXEC. It appears that there's a single scratchpad per process that accumulates the result, and if they're nested you'll get an error when the caller opens this up, and then the callee tries to open it again.

Matthieu, you'd need to maintain separate temp tables for each "type" of result. Also, if you're executing the same one multiple times, you might need to add an extra column to that result to indicate which call it resulted from.

Chris Wuestefeld
A: 

Sadly it is impossible to do this. The problem is, of course, that there is no SQL Syntax to allow it. It happens 'beneath the hood' of course, but you can't get at these other results in TSQL, only from the application via ODBC or whatever.

There is a way round it, as with most things. The trick is to use ole automation in TSQL to create an ADODB object which opens each resultset in turn and write the results to the tables you nominate (or do whatever you want with the resultsets). you can also do it in DMO if you enjoy pain.

A: 

ya yours option is right Mr.Brannon

+2  A: 

I was easily able to do this by creating a SQL2005 CLR stored procedure which contained an internal dataset.

You see, a new SqlDataAdapter will .Fill a multiple-result-set sproc into a multiple-table dataset by default. The data in these tables can in turn be inserted into #Temp tables in the calling sproc you wish to write. dataset.ReadXmlSchema will show you the schema of each result set.

Step 1: Begin writing the sproc which will read the data from the multi-result-set sproc

a. Create a separate table for each result set according to the schema.

CREATE PROCEDURE [dbo].[usp_SF_Read] AS
SET NOCOUNT ON;
CREATE TABLE #Table01 (Document_ID VARCHAR(100)
  , Document_status_definition_uid INT
  , Document_status_Code VARCHAR(100) 
  , Attachment_count INT
  , PRIMARY KEY (Document_ID));

b. At this point you may need to declare a cursor to repetitively call the CLR sproc you will create here:

Step 2: Make the CLR Sproc

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub usp_SF_ReadSFIntoTables()

    End Sub
End Class

a. Connect using New SqlConnection("context connection=true").

b. Set up a command object (cmd) to contain the multiple-result-set sproc.

c. Get all the data using the following:

    Dim dataset As DataSet = New DataSet
    With New SqlDataAdapter(cmd)
        .Fill(dataset) ' get all the data.
    End With
'you can use dataset.ReadXmlSchema at this point...

d. Iterate over each table and insert every row into the appropriate temp table (which you created in step one above).

Final note: In my experience, you may wish to enforce some relationships between your tables so you know which batch each record came from.

That's all there was to it!

~ Shaun, Near Seattle

A: 

Brannon ihave tried your idea of insert into of the stored procedure onsql 2005,and i get into the temp table all of the result set Peleg