SQL return the output of SELECT and not the output of another stored procedure - sql

How do I return the result of the SELECT as the output of the stored procedure? Sorry I'm new to stored procedures!
In this query below I'm calling stored procedure spCuExt_ExtractLog and assigning the result to variable #StartDate. I then use this variable within the main stored procedure, in a SELECT statement. I need to return only the result of the SELECT statement from the main stored procedure:
-- Main stored procedure
BEGIN
DECLARE #StartDate DATETIME
EXEC #StartDate = spCuExt_ExtractLog 'Customers'
SELECT Id, [Name], LogoPath, IsDeleted
FROM dbo.Customers
WHERE RecordCreatedDateUTC>= #StartDate
END
This returns the result of the call to spCuExt_ExtractLog as well as the result of the SELECT statement but I want to output the result of the SELECT only.
How do I do this?

Put the results into a table variable instead:
create procedure dbo.usp_Child
as
begin
select N'Hello world!' as [message];
end;
go
create procedure dbo.usp_Main
as
begin;
declare #results table ([message] nvarchar(max));
insert into #results
execute dbo.usp_Child;
select N'success';
end;
go
execute dbo.usp_Main;

Here's a link to a pretty good document explaining all the different ways to solve your problem (although a lot of them can't be used since you can't modify the existing stored procedure.)
http://www.sommarskog.se/share_data.html

Related

Get first row, first column value from stored procedure

I am calling a stored procedure (that I can't modify) that returns a single value via a SELECT at the end of the procedure. I need to use that value in my own procedure. How can I get that value?
Here is an example of the procedure I am calling that I can not modify:
CREATE PROCEDURE [dbo].[SP_poorlywritten] (
....
)
BEGIN
....
SELECT #lastkey;
RETURN (0);
END
And here is what I am trying to do, but it doesn't work because this gets the return value, and what I need is that SELECT value:
exec #next_key = SP_poorlywritten 'tablename',1;
How can I store the first column, first row value from a store procedure?
If you cannot modify the existing stored procedure, you will not be able to utilize the RETURN as you would like to.
An alternative may be to insert the output of the procedure's select statement into a temp table, and then query that directly to populate a variable.
That would look like this.
CREATE TABLE #tmp
(
LastKey INT
)
INSERT INTO #tmp
EXEC [dbo].[SP_poorlywritten]
See this existing post for more details on how you might accomplish this.
As Aaron Bertrand pointed out, RETURN is for error/status. If you were able to modify the stored procedure, you would want to utilize an output parameter instead of RETURN. This is how you would do that.
CREATE PROCEDURE proc_name
#Output int OUTPUT
AS
<do some stuff>
SET #Output = <some_value>
GO
DECLARE #Output int
EXEC proc_name #Output = #Output

EXEC procedure in dynamic SQL statement only does SELECTs and not INSERTs

I have a stored procedure, let's call it stored procedure 'B'. Stored procedure 'B' calls stored procedure 'A' which returns a resultset that needs to be inserted into a temp table within stored procedure 'B', in order to do further mutations. Because of nested inserts, I have used OPENROWSET (and tried OPENQUERY too).
Now, it seems to work great! However, next to returning a resultset, stored procedure 'A' also does INSERTS in a table. The weird thing is, when stored procedure 'A' is executed from within stored procedure 'B', stored procedure 'A' only returns the resultset, and does NO insert at all. It just seems to skip the entire INSERT INTO statement. I have tried putting dummy SELECT 'test' breakpoints before and after the INSERT, and they are executed fine! How is this possible?
This query looks like this (I changed data and columns up a bit):
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'INSERT INTO #Temp (1,2,3)
SELECT * FROM OPENROWSET (
''SQLOLEDB'',
''Server=(local);TRUSTED_CONNECTION=yes;'',
''SET FMTONLY OFF EXECUTE StoredProcedureA
#Parameter1 = '''''+#InputValue1+'''''
,#Parameter_2 = '''''+#InputValue2+'''''
''
)'
EXEC(#SQL)
No errors are returned. The resultset (SELECT statement from procedure A) is correctly loaded into #Temp within procedure B. But the INSERT that is done within procedure A is not executed.
Does openquery/openrowset not allow INSERTS and only execute SELECT outputs? I thought, maybe its a security/rights issue? Is there any other way to workaround this issue?
Thanks in advance guys!
It is because you are using a temporary table denoted by #.
The scope of this table is ends when your nested stored procedure ends and the temporary table is dropped.
So the insert happens, the table just doesn't exist anymore.
If you create the table before starting your nested procedure you can solve this problem. You can just drop the table in you Procedure B if you really want it gone.

How to query from a stored procedure in SQL Server?

Let say I have a simple Stored Procedure:
ALTER PROCEDURE [dbo].[myProc]
AS
BEGIN
SELECT * FROM myTable
END
How can I do a WHERE statement in Microsoft SQL Server Management Studio to the stored procedure? Something like that:
SELECT * FROM myProc WHERE x = 'a'; -- But that doesn't work...
It sounds like you're trying to make a "dynamic" stored procedure.
Something you might want to do is:
1) Insert the contents of your stored procedure into a temporary table
2) Use dynamic sql to apply a where condition to that temporary table.
Something like:
declare #as_condition varchar(500); --Your condition
create table #a
(
id bigint
)
insert into #a
execute sproc
declare #ls_sql varchar(max);
set #ls_sql = "select * from #a where " + #as_condition;
execute (#ls_sql);
SQL Server allows you to use INSERT INTO to grab a stored procedure's output. For example, to grab all processes with SPID < 10, use:
create table #sp_who (
spid smallint,
ecid smallint,
status nchar(30),
loginame nchar(128),
hostname nchar(128),
blk char(5),
dbname nchar(128),
cmd nchar(16),
request int)
insert into #sp_who execute sp_who
select * from #sp_who where spid < 10
You can't add a WHERE clause to a stored procedure like this.
You should put the clause in the sproc, like this:
ALTER PROCEDURE [dbo].[myProc]
#X VARCHAR(10)
AS
BEGIN
SELECT * FROM myTable WHERE x=#X
END
GO
The syntax for calling a stored procedure is through the use of EXECUTE not SELECT(e.g.):
EXECUTE dbo.myProc 'a'
I think you can't do that.
The command to execute a stored procedure is EXECUTE.
See some more examples of the EXECUTE usage.
I think its better to use a view or a table valued function rather than the suggested approach. Both allow you to pass parameters to the function
If you want the WHERE clause to be something you can "turn off" you can do this, passing in a predetermined value (e.g. -1) if the WHERE limitation is to be bypassed:
ALTER PROCEDURE [dbo].[myProc]
#X VARCHAR(10)
AS
BEGIN
SELECT * FROM myTable WHERE x=#X or #X = -1
END
GO
You must declare a variable in the store procedure which will be necessary to pass to run the stored procedure. Here is an example. Keep this in mind: Before AS you can simply declare any variable by using the # character, but after the AS you must write Declare to declare any variable, e.g., Declare #name nvarchar (50).
ALTER PROCEDURE [dbo].[myProc]
#name varchar (50)
AS
BEGIN
SELECT * FROM myTable
where name= #name
END

Counting results of stored procedure

I have a stored procedure returning ID, Name, Descriptions and takes no input parameters. However, I am interested in how many results do I get.
I expected something like this work:
SELECT COUNT(*) FROM EXEC MyStoredProcedure
But I get the following error in SqlServer Managment Studio:
Incorrect syntax near the keyword 'EXEC'.
Could you show me a little code example how can I do that?
This won't work. May I suggest:
exec MyStoredProcedure
select ##rowcount
Alternatively you could return the count as an output parameter
SELECT ##ROWCOUNT
You need to put the logic in the stored proc and return the count from the stored proc. You do this by using the ##ROWCOUNT variable immediately after your query. This ihow it would work in MS SQL Servet at least.
Stored Proc:
CREATE PROC MyPROC
AS
DECLARE #MyCount int
...
SELECT * FROM MyTable WHERE ...
SELECT #MyCount = ##ROWCOUNT
...
return #MyCOunt
Calling code:
DECLARE #MyCount int
EXEC #MyCount = EXEC MyProc
Write a new stored procedure which does a count for you.

What is the best way to assign the returned value of a stored proc to a variable in SQL?

I have a stored procedure that returns a valueI call it from other stored procedures that need to retrieve this value. The calling stored procedure is inside a transaction, the stored procedure that returns the value (and actually creates the value and stores it in a table that no other proc touches) is not inside its own transaction, but would be part of the caller's transaction.
The question is this, what is the most efficient way of retrieving the return value of the stored procedure and storing it in a variable in the calling proc?
Currently I have the following and I'm wondering if its very inefficient?
DECLARE #tmpNewValue TABLE (newvalue int)
INSERT INTO #tmpNewValue EXEC GetMyValue
DECLARE #localVariable int
SET #localVariable = (SELECT TOP 1 newvalue FROM #tmpNewValue )
Isn't there a more straight forward way of doing this? Isn't this an expensive (in terms of performance) way?
My stored proc doesn't have an output param, it just returns a value. Would using an output param be faster?
For what it's worth I'm using MS SQL Server 2005
If your getting a single return variable then yes this is innefficent you can do:
declare #localVariable int
exec #localVariable =GetMyValue
select #localVariable
See How to Share Data Between Stored Procedures
By some reasons 'exec #localVariable =GetMyValue' is not working for me (MS SQL 2005), it's always return 0 value (They have the same issue).
My opinion is:
if you can change stored procedure, add output parameter.
else if you can remove procedure, rewrite it as a function.
else use table variable, as you do.
Is this proc returning a rowset of 1 row and 1 column or no rowset at all and you just want to capture the returncode?
If you want just the returncode then use Josh's method otherwise use a OUTPUT parameter sicne it will be much faster than what you are doing now
To Explain what I mean run this code
use tempdb
go
create proc GetMyValue
as
select 1
go
create table #temp (id int)
declare #localVariable int
insert #temp
exec #localVariable =GetMyValue
select #localVariable,* from #temp
Try this:
create proc AvilableSeats
as
declare #v1 int,#v2 int
exec #v1= determinPath_Capacity 1,'Sat-Tue',32
exec #v2=Student_fGroup '6/12/2009'
select #v1-#v2