Querying results of a stored procedure - sql

I have a stored procedure that returns a large number of results, and would like a better way to debug/ parse the results than copy/pasting into excel or whatever - is there a way to pass the results of the procedure into a query? e.g., if the procedure call was something like:
exec database..proc 'arg1','arg2','arg3'
my thought was to do something like:
select distinct column1 from
(exec database..proc 'arg1','arg2','arg3')
which clearly did not work, or I wouldn't be here. If it matters, this is for a sybase database.
Thanks!

The code below works in MS SQL 2005. I don't have a Sybase installation right now to test it on that. If it works in Sybase you could use a temporary table (or permanent table) outside of your stored procedure so that you don't have alter the code that you're trying to test (not a very good testing procedure generally.)
CREATE TABLE dbo.Test_Proc_Results_To_Table
(
my_id INT NOT NULL,
my_string VARCHAR(20) NOT NULL
)
GO
CREATE PROCEDURE dbo.Test_Proc_Results_To_Table_Proc
AS
BEGIN
SELECT
1 AS my_id,
'one' AS my_string
END
GO
INSERT INTO dbo.Test_Proc_Results_To_Table (my_id, my_string)
EXEC dbo.Test_Proc_Results_To_Table_Proc
GO
SELECT * FROM dbo.Test_Proc_Results_To_Table
GO

In SQL Anywhere 10 and 11(didn't see whether it's ASA or ASE you're asking about):
SELECT DISTINCT Column1
FROM procName(parameter1, parameter2, parameter3);
I don't have ASE, and I'm not sure if this works on earlier ASA versions.

you could create a temporary table (#temp) in the sp and populate the result set in there. You can later select from the same temp table from the same session. (Or use a global temp table in sybase with ##temp syntax)
This is because what you want to do (select * from exec sp) is not directly possible in sybase

Is it possible to rewrite the stored proc as a function that returns a table? On SQL Server this is certainly possible. Then you can do...
select
<any columns you like>
from
dbo.myFunc( 'foo', 'bar', 1 )
where
<whatever clauses you like>
order by
<same>

I'm not familiar with Sybase, but in MySQL you could use the IN parameter to write one SQL query for all this. Ex:
select distinct column1 from table where column1 in (your_first_query_with_all_the_arguments)

I don't have Sybase installed right now, so some minor syntactic aspect may be wrong here - I can't check, but I used it extensively in the past: select * into #temp from proc_name('arg1','arg2','arg3') should create the local temp table for you automatically with the right columns. Within the same transaction or begin/end block you can access #temp by select * from #temp.

The only real way around this problem is to create a table in your database to store temporary values.
Lets say the stored procedures selects Column1, Column2 & Column3.
Have a table (tempTable) with Column1, Column2, Column3 and set your stored procedure to the following:
CREATE PROCEDURE database..proc
AS
BEGIN
DELETE FROM tempTable
INSERT INTO tempTable (Column1, Column2, Column3)
SELECT Column1, Column2, Column3
FROM Table1
END
then for your sql code to select the values have:
exec database..proc
SELECT Column1, Column2, Column3
FROM tempTable
I hope this helps, I've come across similar problems before and this was the best I could work out.

Related

How to combine 2 results from SQL procedure

I wrote a SQL query, it is 300+ line and I made this as a procedure.
I want to run two times this procedure with different parameters and then want to see all result in one table.
For example:
exec sp_xxxxx 4652,'2022-02-07 00:00:00.000',1
// Returns 2 columns, number of rows can vary
exec sp_xxxxx 4652,'2022-02-14 00:00:00.000',1
// Returns 2 columns, number of rows can vary
I run these together, then I hope to get a result of 4 columns
// 4 column,number of rows can vary
I tried openrowset but SQL blocked.
How can I do this, I would be very happy if you can help.
There's not enough information to provide a demonstrable solution, but the approach should be:
Create temp table #T1(col1, col2)
Create temp table #T2(col1, col2)
Insert into #T1(col1, col2) exec proc
Insert into #T2(col1, col2) exec proc
select t1.col1, t1.col2, t2.col1, t2.col2
from #T1 inner/left/full join #T2 on<criteria>
Also note that prefixing procedures with "sp" is not recommended, this is reserved by MS and indicates a Special Procedure. Choose a different prefix - or no prefix.
Start with creating a table type than matches the output of your procedure.
For example:
CREATE TYPE XxxxxTblType AS TABLE(
Col1 varchar(10) not null,
Col2 decimal(8,2) not null
);
This table type could also be used by your procedure.
Then use a variable with that table type to collect the results from the procedures. Then create a temporary table from that table variable.
declare #Xxxxx XxxxxTblType;
insert into #Xxxxx exec sp_xxxxx 4652,'2022-02-07 00:00:00.000',1;
insert into #Xxxxx exec sp_xxxxx 4652,'2022-02-14 00:00:00.000',1;
select * into #tmpXxxxx from #Xxxxx;
Now you can query the temporary table.
select * from #tmpXxxxx;

UNION with a stored procedure

This is what I am trying to do
EXEC sp1 1
SELECT * FROM x
UNION
if(#num <= 1)
EXEC sp1(2)
else
null //want to return null to stop
I could do this is with a programming language but I don't have an idea what is that I am doing wrong with programming in SQL?
This, honestly, makes no sense, and I still suggest that you use an inline Table-value function here, instead of a procedure, but you can do something like this using OPENROWSET to return the dataset from a stored procedure within a SELECT statement. It can't be parametrised though (not in the traditional sense), and if you don't understand this, don't use it.
This is pseudo SQL as well as there's a lack of enough information to provide a complete solution, such as the columns needed in the SELECTs, but it might get you there if you can comprehend it:
EXEC dbo.sp1 1;
SELECT {Columns}
FROM dbo.x
UNION ALL
SELECT {Same Columns again} --This dataset's definition must be IDENTICAL to the above against your table dbo.x
FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=Yes;Database={YourDatabase}','EXEC dbo.sp1(2);') ORS; --Assumes you are using Windows Authentication
WHERE #Num <= 1
UNION ALL
SELECT NULL,NULL,NULL{,NULL...} --Until you have you enough NULL columns
Note that in this example I am using the deprecated SQLNCLI connection manager. You should really be using MSOLEDBSQL, however, the only instance I currently have access to with a trusted connection is a 2012 instance which doesn't have that driver installed; so I didn't want to post code that I hadn't minimally tested.
You can achieve this in SQL this way:
SELECT * into #temp FROM x
if(#num <= 1)
begin
insert into #temp
EXEC sp1(2)
select * from #temp
end
else
begin
select null
end
First you create a temp table and insert x table records into it and after that you check your condition and then insert records from procedure and then select * from #temp and other case it will return null.

Is it possible to apply SELECT INTO a temporary table from another SELECT?

For some performance improvements, I am looking at using a temporary table rather than a table variable
I am currently putting 100,000s or rows into a table variable using INSERT INTO #table EXECUTE sp_executesql #SQLString (where #SQLString returns a string 'SELECT 'INSERT INTO LiveTable Values('x','y','z') build by dynamic SQL so that the x,y,z values are from the real records)
The INSERT INTO takes a bit of time and I was wondering if, having read about how much better SELECT * INTO #tempTable is, can you do a SELECT * INTO with another SELECT as the source?
So something like
SELECT * INTO #tempTable FROM (SELECT * FROM Table2)
The problem with your query is that all subqueries need a table alias in SQL:
SELECT *
INTO #tempTable
FROM (SELECT * FROM Table2) t;
Short answer is yes (I believe I have done this before, awhile ago, but I don't recall any issues). You can get some more information from this post on msdn:
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/92e5fdf0-e2ad-4f1c-ac35-6ab1c8eec642/select-into-localvarname-from-select-subquery
SELECT * INTO #tempTable FROM (SELECT * FROM Table2)T
SELECT * INTO #tempTable FROM Table2
SELECT * INTO #TempTable
FROM table_name
Yes you can do this, Point to be noted is this #TempTable will be created on the fly, meaning if there is a Temp table that already exists using this error will throw an error as it will try to create a Temp table 1st and then insert the data into it.
To insert data into a table that already exist you will have to use INSERT INTO syntax, something like
INSERT INTO #TempTable --<-- When using this syntax it is best practice to always
SELECT Col1, COl2, .... -- mention the Column names in INSERT INTO and SELECT
FROM TableName -- rather then using SELECT * to makes sure data is being
-- selected from and insert into the RIGHT columns
since you have mentioned you are using it with a stored procedure and would like to use make use of this syntax with store procedure, Im sorry you will not be able to do anything like
SELECT * INTO #Temp Execute usp_Proc
for this you will have to stick with
INSERT INTO #TempTable Execute usp_Proc
The Temp table has to exists before you can insert data into it from a stored Procedure.

SELECT against stored procedure SQL Server

SELECT Val from storedp_Value within the query editor of SQL Server Management Studio, is this possible?
UPDATE
I tried to create a temp table but it didn't seem to work hence why I asked here.
CREATE TABLE #Result
(
batchno_seq_no int
)
INSERT #Result EXEC storedp_UPDATEBATCH
SELECT * from #Result
DROP TABLE #Result
RETURN
Stored Procedure UpdateBatch
delete from batchno_seq;
insert into batchno_seq default values;
select #batchno_seq= batchno_seq_no from batchno_seq
RETURN #batchno_seq
What am I doing wrong and how do I call it from the query window?
UPDATE #2
Ok, I'd appreciate help on this one, direction or anything - this is what I'm trying to achieve.
select batchno_seq from (delete from batchno_seq;insert into batchno_seq default values;
select * from batchno_seq) BATCHNO
INTO TEMP_DW_EKSTICKER_CLASSIC
This is part of a larger select statement. Any help would be much appreciated. Essentially this SQL is broken as we've migrated for Oracle.
Well, no. To select from a stored procedure you can do the following:
declare #t table (
-- columns that are returned here
);
insert into #t(<column list here>)
exec('storedp_Value');
If you are using the results from a stored procedure in this way and you wrote the stored procedure, seriously consider changing the code to be a view or user defined function. In many cases, you can replace such code with a simpler, better suited construct.
This is not possible in sql server, you can insert the results into a temp table and then further query that
CREATE TABLE #temp ( /* columns */ )
INSERT INTO #temp ( /* columns */ )
EXEC sp_MyStoredProc
SELECT * FROM #temp
WHERE 1=1
DROP TABLE #temp
Or you can use OPENQUERY but this requires setting up a linked server, the SQL is
SELECT * FROM (ThisServer, 'Database.Schema.ProcedureName <params>')
The best article (in my opinion) about all possible methods for sharing data between stored procedures in SQL Server you can find here: http://www.sommarskog.se/share_data.html
Try this
Change 'Return'
delete from batchno_seq;
insert into batchno_seq default values;
select #batchno_seq= batchno_seq_no from batchno_seq
RETURN #batchno_seq
to 'Select'
delete from batchno_seq;
insert into batchno_seq default values;
select #batchno_seq= batchno_seq_no from batchno_seq
SELECT #batchno_seq
My approach
select * into new_table from (select t1.col1,t1.col2,..
from table1 t1
union
select t2.cola,t2.colb,..
from table2 t2) as union_table
I MUST be missing something.
Since your stored procedure does not return a result set, and instead returns an integer, using the RETURN functionality of stored procs, you simply CANNOT INSERT into ANY table (since there isn't any result set coming back, at all).
BUT, you can (assuming that this is done iteratively, and not over a set) simply store the return value into a local variable, and insert that variable's value into whatever table is necessary.
However, if you simply want to return the value in the results of a Query Window in SSMS, doing the INSERT and SELECTING is overkill.
It seems to me like THIS would suffice (in a query window):
DECLARE #RetVal INT = 0;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
EXEC #RetVal = storedp_UPDATEBATCH;
COMMIT TRANSACTION;
SELECT #RetVal;
--OR
--PRINT #RetVal;
If this is way far off base, please provide the DDL for "batchno_seq", maybe I can be of better assistance that way.
Cheers!

SQL Select SUM(col) from exec stored_proc?

Is there an easy way in SQL Server (2010) to exec a stored procedure (that returns a table) and sum a column in one (or a few) statements?
eg
SELECT SUM(column) FROM exec proc_GetSomeStuff 'param1', 'param2'
Don't have a server handy to test with, but try this:
declare #temp table(col1 int)
insert into #temp(col1)
exec proc_GetSomeStuff 'param1', 'param2'
select sum(col1) from #temp
Make sure your table variable (or temp table) has the same schema as the results of the stored procedure. If you know that there will be a significant number of rows coming back from the SP, then a temporary table might be a better option. (I'm not sure if table variables can be flushed out to disk if they get too big)