Como atribuir um resultado exec a uma variável sql?

108

Como você atribui o resultado de uma chamada exec a uma variável no SQL? Eu tenho um procedimento armazenado chamado up_GetBusinessDay, que retorna uma única data.

Você pode fazer algo assim:

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

Respostas:

97

Eu sempre uso o valor de retorno para passar de volta o status de erro. Se você precisar retornar um valor, eu usaria um parâmetro de saída.

procedimento armazenado de amostra, com um parâmetro OUTPUT:

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

chamada para o procedimento armazenado, com um parâmetro OUTPUT:

DECLARE @OutputParameter  datetime
       ,@ReturnValue      int

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

RESULTADO:

0
2010-01-01 00:00:00.000
KM.
fonte
10
Usando um parâmetro OUTPUT, você pode retornar qualquer tipo de dados, o valor RETURN de um procedimento armazenado pode ser apenas um número inteiro.
KM.
2
Apenas uma observação: os parâmetros OUTPUT que são declarados com um valor não precisam ser passados. Isso significa que se você estiver alterando um SP existente, poderá fazê-lo com segurança, sem arriscar quebrar nada. por exemplo, @ Param3 datetime = '1900-01-01' OUTPUT.
Morvael
55

Isso funcionará se você quiser simplesmente retornar um número inteiro:

DECLARE @ResultForPos INT 
EXEC @ResultForPos = storedprocedureName 'InputParameter'
SELECT @ResultForPos
Siddhesh Bondre
fonte
13
-1 Isso retornará apenas um número inteiro. O OP deseja retornar uma data. A resposta aceita por @KM. é a resposta correta, pois usa OUTPUT em vez de RETURN.
Code Maverick
4
Na verdade, isso funciona. O exemplo de como obter um inteiro que é retornado, você pode fazer o mesmo para todos os outros tipos (não verifique se a tabela é possível, mas acho que sim). Eu apenas tentei para nvarchar (50).
Mzn
2
@Mzn "você pode fazer o mesmo para todos os outros tipos" , certamente não funciona com UNIQUEIDENTIFIER.
James
1
@James Por quê? O que há de diferente no tipo de dados de identificador único? Os procedimentos armazenados não podem retornar identificadores exclusivos?
Mzn
3
@Mzn UNIQUEIDENTIFIERfoi apenas um exemplo, RETURNfoi projetado para funcionar apenas com valores inteiros, consulte a documentação . A maneira recomendada de obter outros dados de um SP é retornar um conjunto de resultados ou usarOUTPUT
Tiago
34
declare @EventId int

CREATE TABLE #EventId (EventId int)

insert into #EventId exec rptInputEventId

set @EventId = (select * from #EventId)

drop table #EventId 
AZ Chad
fonte
3
na verdade, a única maneira de trabalho descrita aqui além de alterar a assinatura do proc armazenado
Michael Sander
2
Use isso também para uma data, quando o Sproc subjacente também não tem um parâmetro de saída. (Sproc subjacente tinha outro Exec dentro de SQL dinâmico)
Jeff Beagley
3
@MichaelSander Totalmente certo, todas as outras soluções não estão respondendo corretamente à pergunta dos OPs. A única maneira é uma mesa temporária que contém os resultados.
SQL Police
3
Única maneira que funciona aqui sem exigir edições ao proc, o que não posso fazer no meu caso. +1
DLeh
Você também pode usar uma variável de tabela no lugar de uma tabela temporária.
erro de
6

A partir da documentação (supondo que você use o SQL-Server):

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

Então, sim, deve funcionar dessa forma.

Peter Lang
fonte
8
no exemplo do OP, eles desejam retornar uma data, os procedimentos armazenados só podem RETORNAR um valor inteiro para um procedimento de chamada ou um aplicativo.
KM.
0

Eu tive a mesma pergunta. Embora haja boas respostas aqui, decidi criar uma função com valor de tabela. Com uma função com valor de tabela (ou escalar), você não precisa alterar o procedimento armazenado. Eu simplesmente fiz uma seleção na função com valor de tabela. Observe que o parâmetro (MyParameter é 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 atribuir à sua variável, você simplesmente pode fazer algo como:

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

Você também pode usar uma função de valor escalar:

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

Então você pode simplesmente fazer

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