¿Cómo asignar un resultado ejecutivo a una variable SQL?

108

¿Cómo se asigna el resultado de una llamada ejecutiva a una variable en SQL? Tengo un proceso almacenado llamado up_GetBusinessDay, que devuelve una sola fecha.

¿Puedes hacer algo como esto?

exec @PreviousBusinessDay = dbo.up_GetBusinessDay @Date, -1
Prabhu
fuente

Respuestas:

97

Siempre uso el valor de retorno para devolver el estado de error. Si necesita devolver un valor, usaría un parámetro de salida.

ejemplo de procedimiento almacenado, con un parámetro de SALIDA:

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

llamada al procedimiento almacenado, con un parámetro OUTPUT:

DECLARE @OutputParameter  datetime
       ,@ReturnValue      int

EXEC @ReturnValue=YourStoredProcedure 1,null, @OutputParameter OUTPUT
PRINT @ReturnValue
PRINT CONVERT(char(23),@OutputParameter ,121)

SALIDA:

0
2010-01-01 00:00:00.000
KM.
fuente
10
Al usar un parámetro OUTPUT, puede devolver cualquier tipo de datos, el valor RETURN de un procedimiento almacenado solo puede ser un número entero.
KM.
2
Solo una nota al margen, los parámetros de SALIDA que se declaran con un valor no necesitan pasarse. Esto significa que si está alterando un SP existente, puede hacerlo de manera segura sin correr el riesgo de romper nada. por ejemplo, @ Param3 datetime = '1900-01-01' SALIDA.
Morvael
55

Esto funcionará si simplemente desea devolver un número entero:

DECLARE @ResultForPos INT 
EXEC @ResultForPos = storedprocedureName 'InputParameter'
SELECT @ResultForPos
Siddhesh Bondre
fuente
13
-1 Esto solo devolverá un número entero. El OP quiere devolver una fecha. La respuesta aceptada por @KM. es la respuesta correcta, ya que utiliza OUTPUT en lugar de RETURN.
Code Maverick
4
En realidad esto funciona. En el ejemplo de cómo obtener un número entero que se devuelve, puede hacer lo mismo para todos los demás tipos (no verifiqué si la tabla es posible, pero creo que sí). Lo intenté para nvarchar (50).
Mzn
2
@Mzn "puedes hacer lo mismo para todos los demás tipos" , ciertamente no funciona con UNIQUEIDENTIFIER.
James
1
@James ¿Por qué? ¿Qué tiene de diferente el tipo de datos de identificador único? ¿Los procedimientos almacenados no pueden devolver identificadores únicos?
Mzn
3
@Mzn UNIQUEIDENTIFIERfue solo un ejemplo, RETURNestá diseñado para funcionar solo con valores enteros, consulte los documentos . La forma recomendada de obtener otros datos de un SP es devolver un conjunto de resultados o usarOUTPUT
James
34
declare @EventId int

CREATE TABLE #EventId (EventId int)

insert into #EventId exec rptInputEventId

set @EventId = (select * from #EventId)

drop table #EventId 
AZ Chad
fuente
3
en realidad, la única forma de trabajo descrita aquí aparte de cambiar la firma del proceso almacenado
Michael Sander
2
Usé esto también para una fecha, cuando el Sproc subyacente tampoco tiene un parámetro de salida. (Sproc subyacente tenía otro Exec dentro de SQL dinámico)
Jeff Beagley
3
@MichaelSander Totalmente en lo cierto, todas las demás soluciones no responden correctamente a la pregunta de los OP. La única forma es una tabla temporal que contiene los resultados.
SQL Police
3
La única forma en que funciona aquí sin requerir ediciones en el proceso, lo cual no puedo hacer en mi caso. +1
DLeh
También puede utilizar una variable de tabla en lugar de una tabla temporal.
error
6

De la documentación (asumiendo que usa SQL-Server):

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

Entonces sí, debería funcionar de esa manera.

Peter Lang
fuente
8
en el ejemplo de OP, quieren devolver una fecha, los procedimientos almacenados solo pueden DEVOLVER un valor entero a un procedimiento de llamada o una aplicación.
KM.
0

Tenía la misma pregunta. Si bien aquí hay buenas respuestas, decidí crear una función con valores de tabla. Con una función con valor de tabla (o escalar), no tiene que cambiar su proceso almacenado. Simplemente hice una selección de la función con valores de tabla. Tenga en cuenta que el parámetro (MyParameter es opcional).

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;
)

Para asignar a su variable, simplemente puede hacer algo como:

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

También puede utilizar una función con valores escalares:

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

Entonces puedes simplemente hacer

Declare @MyDate datetime;
SET @MyDate = (Select dbo.TestDateFunction());
SELECT @MyDate;
CodeCaptain
fuente