Select stored procedure results into tables - sql-server

I have stored procedure which returns multiple data sets and I need to create tables based on that data sets to get data types. Found this code
SELECT *
INTO newTable
FROM OPENROWSET ('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;',
'EXEC ISS.dbo.sp')
but it works only for first result set and I need tables for all results

As far as I know, cleaner way of using stored procedure output to populate data to a table is a much required solution. There are many ways including the ones you have shown above, but every technique has its own plus and minus.
The solution I have used is create global temporary table
I don't know if it suits for our need.

Once OpenTable is created you can do this over and over again:
Insert into OpenTable
Exec dbo.proc55

Related

How can I Identify in stored procedure if a certain column is being updated?

I need to do a check to see which stored procedures have table updates in them that don't update certain columns. I found the code of the stored procedure in the sys.sql_modules, but I don't know how could I make this check. The stored procedures may contain more UPDATEs and INSERTs. I am using Microsoft SQL.
Assuming you are curious to find stored procedures that update TblA and do not update ColA, you could do something like:
SELECT * FROM sys.sql_modules
WHERE definition LIKE 'UPDATE TblA' AND
definition NOT LIKE 'SET ColA';
This can get ugly if people do not format their source well, but you can adapt this technique to handle that if you need to.

SQL Server : 2 Stored Procedure 1 for XML & one for data

I have 2 systems that use the same stored procedure.
The problem is that one system needs data as normal select statement inside the stored procedure, while the other needs the data in XML format
I just looking for best practice,
do I have to create 2 stored procedures so each system read from its own stored procedure?
or I create one stored procedurefor normal data and the other stored procedure read data from the first one and fill it in temp table using OPENROWSET?
or add a parameter for data output so if I want data i pass 1 if I want xml I pass 2?
any other suggestions?
Thanks
Depends on the details of the stored procedure but as a rule of thumb I prefer to add a parameter to determine the output type. In this way you will avoid to maintain two procedures and the risk of going out of sync at some point in the future.
I would suggest Two Stored Procedures. as using OPENROWSET might have some performance issues.
When you say you need data in XML format, this query will look very different from the query which returns data in rowset and both queries will have a very different execution plan.
So if you decide to embed this non-XML procedure inside a OPENROWSET query and then try to pull XML OUTPUT from that query might result in a very inefficient query plan.
I would say simply create Two Separate procedures and have two separate Execution plans for each procedure which can possibly result in a better performance.
Another Option that comes to my mind is that you can add a Parameter to your Procedure like #XML_OUTPUT and at run time check the value of Parameter and run respective queries, something like this...
CREATE PROCEDURE Get_DATA
#Param1 DataType,
#Param2 DataType,
#XML_OUTPUT BIT
AS
BEGIN
SET NOCOUNT ON;
IF (#XML_OUTPUT = 1)
BEGIN
SELECT *
FROM TABLE
FOR XML PATH('')..... bla bla
END
ELSE
BEGIN
SELECT *
FROM TABLE ... bla bla
END
END
And at run time if #XML_OUTPUT was set to 1 , the procedure will return XML Data, else it will return non-xml data.

get resultset from stored procedure

i have a stored proc A that contains a stored proc B.
stored proc B does an insert and returns a row of information.
is there a way to access that info in stored proc A?
You can execute the stored procedure and selected it into a temp table.
Create #table ()....
INSERT INTO #table EXEC your_procedure
The only time when it really becomes difficult (and maybe impossible, I've never seen it done) is when the stored procedure returns multiple recordsets (not multiple records) and the recordsets have different fields.
EDIT:
You can can also use a table variable (DECLARE #my_table TABLE()) to do the same thing. In your situation you'll want to try both and see which is better.
http://www.sql-server-performance.com/2007/temp-tables-vs-variables/
You could create a temp table and then insert-exec from the inner procedure call.
Share Data
Scroll down to the Insert-Exec section.
I will recommend you to create a Table variable and insert the row information into it
EDIT:
Please note that it will be useful if not under Transaction and not joining it with other tables and just acting as a intermediate for containing row information as you just said in the query.

Get column names/types returned from a stored procedure

Is there a way via metadata (Information_Schema, perhaps?) to get a list of the columns a sproc will return? I'm trying to automate some code generation and that would help tremendously...
Unless you're prepared to parse the contents of ROUTINE_DEFINITION in INFORMATION_SCHEMA.ROUTINES, then your best bet will be to execute the procedures, and read the column information from the records returned.
In .NET you can do this by reading the results of the stored procedure into a DataTable and querying the Columns property.
The reason there's no easy way to do this is a stored procedure could potentially return different result sets based on the parameters. There's no fixed result set format like there is with user defined functions.
Edit
As mentioned in the other answer, you will need to use SET FMTONLY ON to ensure no data is returned. There are some situations where SET FMTONLY won't work, e.g. when using #temp tables in your stored procedures, but there is a workaround.
I just ran Profiler to see how Visual Studio does this for the strongly typed dataset drag and drop.
This is the code it sent.
SET NO_BROWSETABLE ON;
SET FMTONLY ON;
exec dbo.aspnet_Roles_GetAllRoles #ApplicationName=NULL
So I presume there might not be any "more official" way of doing it.
Obviously you would need to bear in mind that a single stored procedure might return multiple result sets or different result sets dependant on the parameters passed.
For people on 2012+ another approach might be to use sp_describe_first_result_set
My way of doing this:
Edit the stored procedure to have an INTO clause:
Change
Select * from tablename
to
Select * INTO _tablename FROM tablename
This creates a table in the database.
Then, use SELECT * FROM INFORMATION_SCHEMA WHERE TABLE_NAME = '_tablename'
Don't forget to undo the modification to the sproc.

Calling a Stored Proc from within a Stored Proc and returning a recordset

I have a Stored Procedure that rolls-back a series of operations. I want to call this from within another SP.
The problem is that the inner SP returns a record set with a single value that indicates the degree of success.
This approach worked well and has some advantages in our context, but in retrospect, I would have done it the conventional way with a Return value or an Output parameter.
I could always change this SP to use this approach and modify the calling code, but a) I don't want to dabble with any more code than I have to, and b) at an intellectual level, I'm curious to see what alternative solution there may be, if any.
How (if at all) can I call this SP and determine the value of the singleton recordset returned?
Thanks
A stored procedure returns a record set like any other, so you can actually do this:
INSERT INTO MyTable (
MyValue
)
EXEC dbo.MyStoredProcedure
The EXEC takes the place of a SELECT statement. To get the value, just SELECT from the table you inserted into. Typically, this would be a temp table.
The other option is to convert the stored procedure that returns a recordset into a function that returns a table.
Ant's approach is probably best if you want to minimize the changes to your system.
Normally you would use a temporary table for that approach since you can't use an exec statement to insert into a table variable.
Here's a variation which will work well if you need to use this for MULTIPLE recordsets.
CREATE TABLE #outsidetable (...)
exec spInsideProcedure
SELECT * FROM #outsidetable
inside spInsideProcedure
INSERT INTO #outsidetable SELECT <blah blah blah>
I tried Ant's approach and it worked a treat:
Declare #Success tinyint
Declare #Response Table (Success int)
Insert into #Response(Success)
Exec Fix_RollbackReturn 12345, 15
Select #Success=Success from #Response
As you can see I used a Table Variable rather than a temporary table because slightly more efficient than a temporary table.
Thanks for all your help guys.
EDIT: It appears that Dave was right after all. That is, my Exec-into-Table-variable approach worked on my SQL2005 development machine, but when moved to the Live (SQL2000) machine it objected, so I had to change to the temporary table approach.
It's a little annoying, especially since in a couple of weeks we are upgrading to SQL2005 across the board(!).

Resources