accessing multiple resultset in sql server - sql

I am working with sql server 2005 and working with an old stored proc which was written by someone else. I just want to call that stored proc to get data and not modify it.
The problem is that the stored proc is returning multiple result set with exactly same fields. Just the data is bit different. So when that stored proc is being called in the front end it is being used to populate two diffrent data tables which is fine.
But now I need to work with the combined results in excel and so dont have the advantages of multiple data tables.
Basically I want create a new stored proc which returns the union of the two results just by calling the existing storedproc. I dont want to create another copy of stored proc as I will have to keep tab everytime the other stored proc is changed i will have to change mine.
Is there a way to access the second result set in sql server itself.
Thanks,
--Abhi

Create a proxy procedure that throws both sets into a temp table, and select from that.
Here's a test example...
/*Create first proc that returns two data sets*/
IF OBJECT_ID('ReturningTwoDataSets') IS NOT NULL
BEGIN
DROP PROCEDURE ReturningTwoDataSets
END
GO
CREATE PROCEDURE dbo.ReturningTwoDataSets
AS
BEGIN
SET NOCOUNT ON
SELECT '1' AS [col1]
,'2' AS [col2]
,'3' AS [col3]
SELECT '4' AS [col1]
,'5' AS [col2]
,'6' AS [col3]
END
GO
/*
Create new proc that combines both data sets
into a temp table and returns a single dataset
*/
IF OBJECT_ID('ReturningOneDataSet') IS NOT NULL
BEGIN
DROP PROCEDURE ReturningOneDataSet
END
GO
CREATE PROCEDURE dbo.ReturningOneDataSet
AS
BEGIN
SET NOCOUNT ON
IF OBJECT_ID('TempDB..#OneDataSet') IS NOT NULL
BEGIN
DROP TABLE #OneDataSet
END
CREATE TABLE #OneDataSet
(
[col1] VARCHAR(100)
,[col2] VARCHAR(100)
,[col3] VARCHAR(100)
)
INSERT INTO #OneDataSet
(
col1
,col2
,col3
)
EXEC ReturningTwoDataSets
SELECT * FROM #OneDataSet
END
GO
/*Execute the old proc*/
EXEC ReturningTwoDataSets
/*Execute the new proc*/
EXEC ReturningOneDataSet

Related

Insert results of a table into stored procedure as parameters

I have a stored procedure which inserts values into a table.
Let's say its name is usp_InsertTableA with parameters #ID int and Name varchar(100).
I have a requirement to call this stored procedure multiple times from another stored procedure. I am thinking to call this stored procedure something like below
exp usp_InsertTableA
select ID, Name from #tempTable
Is this possible in SQL Server to execute this with the value of the table and send it into a stored procedure?
You can use table type parameters to stored procedure.
CREATE TYPE [dbo].[udt_MyCustomTable] AS TABLE(
[id] [int] NOT NULL,
[name] [nvarchar](100) NOT NULL
)
GO
And then you stored procedure would be:
CREATE PROC [dbo].[usp_InsertTableA]
(
#myCustomTable udt_MyCustomTable READONLY
)
AS
BEGIN
-- Your code goes in here
END
Is this possible in SQL Server to execute this with the value of the table and send it into a stored procedure?
No, not with the stored procedure you have there. There are ugly hacks that could make it happen, but it's not how you're supposed to do things in T-SQL. Everything you do in SQL Server is supposed to be optimized to work on a set of rows, not a single row / row by row
In practice what this means is, if you have a query like this that produces 100 rows:
select ID, Name from #tempTable
You would pass those 100 rows to your insert procedure and insert them in one operation:
--expanding on sam's advice
--create a type
CREATE TYPE [dbo].[udt_MyCustomTable] AS TABLE(
[id] [int] NOT NULL,
[name] [nvarchar](100) NOT NULL
)
--your insert procedure
CREATE PROC [dbo].[usp_InsertTableA]
(
#myCustomTable udt_MyCustomTable READONLY
)
AS
BEGIN
INSERT INTO TableA(idcolumn, namecolumn)
SELECT is, name FROM #myCustomTable
END
Now in your main sp that wants to insert 100 rows:
#DECLARE tmpVar udt_MyCustomTable;
--put 100 rows into table variable
INSERT INTO tmpVar(id,name)
select ID, Name from #tempTable
--pass 100 rows in variable to SP to insert all at once
EXECUTE usp_InsertTableA tmpVar
DECLARE #ID INT, #Name VARCHAR(255)
SELECT #ID = ID, #Name=Name FROM #tempTable -- assumes one record in the table.
EXEC dbo.usp_insertdata #id, #Name

Parameter not set still passing value in stored procedure sql

ALTER PROCEDURE [dbo].[XXXXX]
#type varchar(20)
,#Name varchar(20)
,#DayVal int
,#MonthVal int
,#YearVal int
AS
BEGIN
If type='yyy'
begin
insert into dbo.destinationDB
(name,Dayval,Monthval,Yearval)
values
(#name,#DayVal,#MonthVal,#YearVal)
In the above Stored procedure of SQL Server the parameters #name, #DataVal, #MonthVal, #YearVal is not defined anywhere neither the values are set in any other Stored Procedures or Jobs . But it still passing values and values are updated in the destination table.
If there is another procedure or trigger calling your proc you will find it in the sys.sql_module:
SELECT OBJECT_NAME(object_id), *
FROM sys.sql_modules
WHERE definition LIKE '%XXXX%' -- your proc name
If it is not there there are at least 3 possible scenarios:
there is a linked server calling your server
there is an external application
someone else is calling it from ssms
You're probably comparing with null, try adding and type IS NOT NULL

How to use the return table data of one procedure in another procedure?

I had a procedure it will return data from a temporary table.The temporary table structure may varies depends on the input parameter of the procedure.This procedure is a general procedure so i cant modify this one.
My requirement is that i want to use the return temporary table data to do some calculation from another procedure.Is it possible to achieve this one????
requirement is some thing like this
Create Procedure Proc2 ( #Condition int)
As
BEGIN
execute #temp = Proc1 input1,input2
select * from #temp where column1 = #Condition
END
This Proc1 is using in some other procedures also so i cant include the condition inside Proc1.
Am using SQL SERVER 2008 R2
Thejus T V
You need to create a temporary table and use like this
Create Procedure Proc2 ( #Condition int) As
BEGIN
create table #temp(col1 int, col2,....) -- similar to reseultset of proc1
insert into #temp
execute Proc1 input1,input2
select * from #temp where column1 = #Condition
END
If the column names are unknown you can use OPENROWSET
Select
*
from
OPENROWSET('SQLOLEDB','Data Source=Server_name;Trusted_Connection=yes;
Integrated Security=SSPI','Execute yourdb..proc1')
If you know the structure being returned by the procedure then you can simply create a temp table and insert the data into that temp table from the stored procedure result set.
Create Table #Temp (Col INT , Col2 INT)
INSERT INTO #Temp
Exec Proc1 input1,input2
But since you have mentioned you don't know the exact structure of the table begin returned from the stored procedure you can use OPENQUERY to manipulate further the result set of a stored procedure something like this....
SELECT *
FROM OPENQUERY(YOURSERVERNAME, 'Proc1 input1,input2')
where column1 = #Condition

Unable to call stored procedure within stored procedure

I have three stored procedures A, B, C
and definition of A is like
StoredProcedure A
As
Begin
--Some Stuff
Exec DBO.B [Derived Conitions]
Exec DBO.C [Derived Conitions]
END
but whenever I tried to execute the stored procedure A, at parsing time it give waring;
The module 'A' depends on the missing object 'B'. The module will still be created;
however, it cannot run successfully until the object exists.
The module 'A' depends on the missing object 'C'. The module will still be created;
however, it cannot run successfully until the object exists.
At execution time it throws exception
Could not find stored procedure 'dbo.B'.
Could not find stored procedure 'dbo.C'.
I found so many answers for calling a stored procedure with in stored procedure, but none of them worked for me.
You certainly can execute multiple procedures from within a single SP. You can even us the results from 1 SP as parameters in another.
In your specific case I suspect that there is a permissions / security or collation error which is stopping you from access the B and C stored procs.
Here is an example of SP chaining at work.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[DerivedProcedures]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Temporary table used to store results from SP1
DECLARE #Results_ForStoredProcedure1 TABLE
(
[SPID] INT,
[Status] NVARCHAR(50),
[Login] NVARCHAR(50),
[HostName] NVARCHAR(50),
[BlkBy] NVARCHAR(5),
[DBName] NVARCHAR(50),
[Commad] NVARCHAR(50),
[CPUTime] INT,
[DiskIO] INT,
[LastBatch] NVARCHAR(50),
[ProgramName] NVARCHAR(50),
[SPID2] INT,
[RequestId] INT
)
-- Execute SP1
INSERT INTO #Results_ForStoredProcedure1
EXEC sp_who2
-- Temporary table to store the results from SP2
DECLARE #Results_ForStoredProcedure2 TABLE
(
[DatabaseName] NVARCHAR(50),
[DatabaseSize] INT,
[Remarks] NVARCHAR(50)
)
-- Execute SP2
INSERT INTO #Results_ForStoredProcedure2
EXEC sp_databases
-- do something with both SP results
SELECT DISTINCT SP2.*
FROM #Results_ForStoredProcedure1 AS SP1
INNER JOIN #Results_ForStoredProcedure2 AS SP2 ON SP2.DatabaseName = SP1.DBName
WHERE SP1.DBName IS NOT NULL
END
GO
-- TEST
EXECUTE [dbo].[DerivedProcedures]
Perhaps, it sounds hilarious but I was getting the mentioned issue as I was using the wrong DB name (for example-Use 'XYZ'). Actually, in my case I was transferring a SP from one environment to another but after doing so I would not change the corresponding DB name .Due to which I was getting the error as the SPs which were involved were present in different DBs in the dissimilar environment.
In nutshell,please check the DB name which should be the very first line of your SP.
For example- Use 'XYZ'.

How do I combine result sets from two stored procedure calls?

I have a following stored procedure
CREATE PROCEDURE [dbo].[MyStored]
#state int
AS
SELECT blahblahblah WHERE StoredState=#state LotsOfJoinsFollow;
RETURN 0
and I'd like to call that stored procedure with #state being 0 and 1 and have the result sets returned by both calls combined with UNION semantics so that I have a new resultset that has rows from both the first call and the second call.
Something like (imaginary SQL):
(EXEC MyStored 0) UNION (EXEC MyStored 1);
How do I achieve that?
This may be oversimplifying the problem, but if you have control over the sp, just use in rather than =:
CREATE PROCEDURE [dbo].[MyStored]
AS
SELECT blahblahblah WHERE StoredState IN (0,1) LotsOfJoinsFollow;
RETURN 0
If this is not an option, just push the results of both sproc calls into a temp table:
/*Create a table with the same columns that the sproc returns*/
CREATE TABLE #tempblahblah(blahblahblah NVARCHAR(50))
INSERT #tempblahblah ( blahblahblah )
EXEC MyStored 0
INSERT #tempblahblah ( blahblahblah )
EXEC MyStored 1
SELECT * FROM #tempblahblah
create table #table (
.....
)
insert into #table exec MyStored 0
insert into #table exec MyStored 1
select * from #table
drop table #table
Alternatively to a series of statements like these:
INSERT INTO #YourTempTable
EXEC MyStored 0;
INSERT INTO #YourTempTable
EXEC MyStored 1;
you could use one INSERT ... EXEC statement like below:
INSERT INTO #YourTempTable
EXEC ('
EXEC MyStored 0;
EXEC MyStored 1;
');
The results of the two calls to MyStored would be UNIONed (or, rather, UNION ALLed), just like with the former method.
A long way would be to create a wrapper that does this - a function that takes a list of states and adds them to a final table that would be returned.
You could also have whatever technology is calling this procedure do the concatination of records (i.e. having .NET append the result set of each state you are looking into)
If you're fine with passing in a list of states to your 'state' param, you could create a dynamic sql query
CREATE PROCEDURE [dbo].[MyStored]
#state nvarchar(150)
AS
-- #state needs to be pre-formatted in a list for an in-clause
-- i.e. 1,2,10 (if it was a string list, you'd need to do use double single quotes around the items - ''1'',''2'',''10''
DECLARE #SQL nVarChar(5000) = '
SELECT blahblahblah
FROM LotsOfJoins
WHERE StoredState in (' + #state + ')'
exec sp_executeSql #sql
This works great for simple procedures; although, it can get take longer to maintain if changes are needed down the road.
.
Here is a CodeProject Article and a MS SQL Tips Article that does a better job going into details
.
EDIT: The param #state will need to be a nVarChar since your passing in a comma delimited list of int values
If the stored procedure you are calling has a temp table with the same name as one in the calling procedure you will get this error.
e.g. sp1 has temp table #results
sp2 create table #results(fields)
then trying to insert into #results in sp2 the result of calling sp1 would fail with this error. change temp table in sp2 to #result and try again and you should see this now works.