136

How do you assign the result of an exec call to a variable in SQL? I have a stored proc called up_GetBusinessDay, which returns a single date.

Can you do something like this:

exec @PreviousBusinessDay = dbo.up_GetBusinessDay @Date, -1
Code Maverick
  • 20,171
  • 12
  • 62
  • 114
Prabhu
  • 12,995
  • 33
  • 127
  • 210

7 Answers7

120

I always use the return value to pass back error status. If you need to pass back one value I'd use an output parameter.

Here's a sample stored procedure, with an OUTPUT parameter:

CREATE PROCEDURE YourStoredProcedure 
(
    @Param1 int
   ,@Param2 varchar(5)
   ,@Param3 datetime OUTPUT
)
AS
    IF ISNULL(@Param1, 0) > 5
    BEGIN
        SET @Param3 = GETDATE()
    END
    ELSE
    BEGIN
        SET @Param3 = '1/1/2010'
    END
    
    RETURN 0
GO

Here's an example of calling the stored procedure, with an OUTPUT parameter:

DECLARE @OutputParameter datetime
       ,@ReturnValue     int

EXEC @ReturnValue = YourStoredProcedure 1, NULL, @OutputParameter OUTPUT

PRINT @ReturnValue
PRINT CONVERT(char(23), @OutputParameter, 121)

Output:

0
2010-01-01 00:00:00.000
CarenRose
  • 1,266
  • 1
  • 12
  • 24
KM.
  • 101,727
  • 34
  • 178
  • 212
  • 12
    By using an OUTPUT parameter, you can return back any data type, the RETURN value from a stored procedure can only be an integer. – KM. Feb 11 '10 at 18:14
  • 2
    Just a side note, OUTPUT parameters that are declared with a value don't need to be passed in. This means that if you are altering an existing SP you can do it safely without risking breaking anything. eg ,@Param3 datetime = '1900-01-01' OUTPUT. – Morvael Oct 25 '16 at 10:07
67

This will work if you wish to simply return an integer:

DECLARE @ResultForPos INT 
EXEC @ResultForPos = storedprocedureName 'InputParameter'
SELECT @ResultForPos
Matthew Lock
  • 13,144
  • 12
  • 92
  • 130
Siddhesh Bondre
  • 771
  • 5
  • 2
  • 16
    -1 This will only return an integer. The OP wants to return a date. The accepted answer by @KM. is the correct answer, as it uses OUTPUT instead of RETURN. – Code Maverick May 07 '14 at 00:41
  • 6
    Actually this works. The example as to how to get an integer that is returned, you can do the same for all other kinds (didn't check if table possible, but I think yes.) I just tried it for nvarchar(50). – Lzh May 18 '14 at 04:39
  • 3
    @Mzn *"you can do the same for all other kinds"*, certainly doesn't work with `UNIQUEIDENTIFIER`. – James Jun 09 '16 at 09:20
  • 3
    @James Why? What's different about the uniqueidentifier datatype? Stored procedures cannot return uniqueidentifiers? – Lzh Jun 09 '16 at 09:50
  • 4
    @Mzn `UNIQUEIDENTIFIER` was just an example, `RETURN` is designed to only work with integer values, see the [docs](https://msdn.microsoft.com/en-us/library/ms174998.aspx). The recommended way of getting other data from an SP is to either return a result set or use `OUTPUT` – James Jun 09 '16 at 12:21
  • I am understanding you more now as the docs for Stored procedures (https://msdn.microsoft.com/en-us/library/ms187926.aspx) doesn't mention anything about returning "values" except through resultsets and OUTPUT params... returning anything other than an integer applies for FUNCTIONS and I wonder why is it working for PROCS even thought it's not designed to be used like that. – Lzh Jun 23 '16 at 16:07
  • In 2016, this only works for int and nvarchar (or variants of the two). Alas, that doesn't include bigint or other common modern primary keys. We get to use output parameters or table returns as in other answers. – Guy Schalnat Aug 28 '17 at 15:40
44
declare @EventId int

CREATE TABLE #EventId (EventId int)

insert into #EventId exec rptInputEventId

set @EventId = (select * from #EventId)

drop table #EventId 
AZ Chad
  • 1,616
  • 1
  • 15
  • 20
  • 6
    actually the only working way decribed here apart from changing the stored proc's signature – Michael Sander Aug 31 '16 at 07:43
  • 3
    Used this as well for a date, when the underlying Sproc doesn't have an output parameter either. (Underlying sproc had another Exec inside it from dynamic SQL) – Jeff Beagley Sep 27 '16 at 22:16
  • 4
    @MichaelSander Totally right, all other solutions are **not** correctly answering the OPs question. The only way is a temporary table which holds the results. – SQL Police Oct 05 '16 at 08:17
  • 5
    Only way that works here without requiring edits to the proc, which I can't do in my case. +1 – DLeh Feb 16 '17 at 21:33
  • 1
    You can also use a table variable in place of a temp table. – error Mar 14 '19 at 14:58
6

From the documentation (assuming that you use SQL-Server):

USE AdventureWorks;
GO
DECLARE @returnstatus nvarchar(15);
SET @returnstatus = NULL;
EXEC @returnstatus = dbo.ufnGetSalesOrderStatusText @Status = 2;
PRINT @returnstatus;
GO

So yes, it should work that way.

Peter Lang
  • 54,264
  • 27
  • 148
  • 161
  • 9
    in the OP's example they want to return a date, Stored procedures can only RETURN an integer value to a calling procedure or an application. – KM. Feb 11 '10 at 18:13
  • This is incorrect. That documentation is talking about a scalar function. The OP is asking about a stored procedure with its resultset. @KM. note even the source documentation is assigning the returned value to nvarchar(15), not int. – youcantryreachingme Sep 15 '20 at 01:00
4

I had the same question. While there are good answers here I decided to create a table-valued function. With a table (or scalar) valued function you don't have to change your stored proc. I simply did a select from the table-valued function. Note that the parameter (MyParameter is optional).

CREATE FUNCTION [dbo].[MyDateFunction] 
(@MyParameter varchar(max))
RETURNS TABLE 
AS
RETURN 
(
    --- Query your table or view or whatever and select the results.
    SELECT DateValue FROM MyTable WHERE ID = @MyParameter;
)

To assign to your variable you simply can do something like:

Declare @MyDate datetime;
SET @MyDate = (SELECT DateValue FROM MyDateFunction(@MyParameter));

You can also use a scalar valued function:

CREATE FUNCTION TestDateFunction()  
RETURNS datetime  
BEGIN  
    RETURN (SELECT GetDate());
END

Then you can simply do

Declare @MyDate datetime;
SET @MyDate = (Select dbo.TestDateFunction());
SELECT @MyDate;
CodeCaptain
  • 379
  • 4
  • 10
2

Here is solution for dynamic queries.

For example if you have more tables with different suffix:

dbo.SOMETHINGTABLE_ONE, dbo.SOMETHINGTABLE_TWO

Code:

DECLARE @INDEX AS NVARCHAR(20)
DECLARE @CheckVALUE AS NVARCHAR(max) = 'SELECT COUNT(SOMETHING) FROM 
dbo.SOMETHINGTABLE_'+@INDEX+''
DECLARE @tempTable Table (TempVALUE int)
DECLARE @RESULTVAL INT

INSERT INTO @tempTable
    EXEC sp_executesql @CheckVALUE

SET @RESULTVAL = (SELECT * FROM @tempTable)

DELETE @tempTable

SELECT @RESULTVAL 
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
1

You can use a Table Variable for that

Code:

DECLARE @PreviousBusinessDay DATETIME
DECLARE @Temp TABLE(BusinessDay DATETIME)
INSERT INTO @Temp EXEC dbo.up_GetBusinessDay @Date, -1
SET @PreviousBusinessDay = (SELECT * FROM @Temp)
SELECT @PreviousBusinessDay

https://www.sqlservertutorial.net/sql-server-user-defined-functions/sql-server-table-variables/

FelipeHSouza
  • 305
  • 1
  • 3
  • 10