Jak przypisać wynik exec do zmiennej sql?

108

Jak przypisać wynik wywołania exec do zmiennej w SQL? Mam wywołany zapisany proces up_GetBusinessDay, który zwraca pojedynczą datę.

Czy możesz zrobić coś takiego:

exec @PreviousBusinessDay = dbo.up_GetBusinessDay @Date, -1
Prabhu
źródło

Odpowiedzi:

97

Zawsze używam wartości zwracanej do przekazywania stanu błędu. Jeśli chcesz przekazać jedną wartość, użyłbym parametru wyjściowego.

przykładowa procedura składowana z parametrem 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

wywołanie procedury składowanej z parametrem OUTPUT:

DECLARE @OutputParameter  datetime
       ,@ReturnValue      int

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

WYNIK:

0
2010-01-01 00:00:00.000
KM.
źródło
10
Używając parametru OUTPUT, można zwrócić dane dowolnego typu, wartość RETURN z procedury składowanej może być tylko liczbą całkowitą.
KM.
2
Na marginesie, parametry OUTPUT, które są zadeklarowane z wartością, nie muszą być przekazywane. Oznacza to, że jeśli zmieniasz istniejący SP, możesz to zrobić bezpiecznie bez ryzyka zepsucia czegokolwiek. np. @ Param3 datetime = '1900-01-01' OUTPUT.
Morvael
55

To zadziała, jeśli chcesz po prostu zwrócić liczbę całkowitą:

DECLARE @ResultForPos INT 
EXEC @ResultForPos = storedprocedureName 'InputParameter'
SELECT @ResultForPos
Siddhesh Bondre
źródło
13
-1 Zwróci tylko liczbę całkowitą. OP chce zwrócić datę. Zaakceptowana odpowiedź od @KM. jest poprawną odpowiedzią, ponieważ używa OUTPUT zamiast RETURN.
Code Maverick
4
Właściwie to działa. Przykład, jak uzyskać zwracaną liczbę całkowitą, możesz zrobić to samo dla wszystkich innych rodzajów (nie sprawdzałem, czy tabela jest możliwa, ale myślę, że tak). Właśnie wypróbowałem to dla nvarchar (50).
Mzn
2
@Mzn „możesz zrobić to samo dla wszystkich innych rodzajów” , z pewnością nie działa UNIQUEIDENTIFIER.
James
1
@James Why? Czym różni się typ danych uniqueidentifier? Procedury składowane nie mogą zwracać unikalnych identyfikatorów?
Mzn
3
@Mzn UNIQUEIDENTIFIERbył tylko przykładem, RETURNzostał zaprojektowany do pracy tylko z wartościami całkowitymi, zobacz dokumentację . Zalecanym sposobem uzyskiwania innych danych z SP jest zwrócenie zestawu wyników lub użycieOUTPUT
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
źródło
3
właściwie jedyny działający sposób opisany tutaj, oprócz zmiany podpisu przechowywanego procesu
Michael Sander
2
Użyto tego również w przypadku daty, gdy bazowy Sproc również nie ma parametru wyjściowego. (Podstawowy sproc miał w sobie inny plik Exec z dynamicznego SQL)
Jeff Beagley
3
@MichaelSander Całkowicie zgadza się, wszystkie inne rozwiązania nie odpowiadają poprawnie na pytanie PO. Jedynym sposobem jest tymczasowa tabela zawierająca wyniki.
SQL Police
3
To jedyny sposób, który działa tutaj bez konieczności edycji proc, czego nie mogę zrobić w moim przypadku. +1
DLeh
Możesz również użyć zmiennej tabeli zamiast tabeli tymczasowej.
błąd
6

Z dokumentacji (zakładając, że używasz SQL-Server):

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

Więc tak, to powinno działać w ten sposób.

Peter Lang
źródło
8
w przykładzie OP chcą zwrócić datę, procedury składowane mogą tylko ZWRACAĆ wartość całkowitą do procedury wywołującej lub aplikacji.
KM.
0

Miałem to samo pytanie. Chociaż są tutaj dobre odpowiedzi, zdecydowałem się utworzyć funkcję o wartościach tabelarycznych. Dzięki funkcji wartościowanej tabelowo (lub skalarnie) nie musisz zmieniać przechowywanej procedury. Po prostu wybrałem funkcję z wartościami tabelarycznymi. Zwróć uwagę, że parametr (MyParameter jest opcjonalny).

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

Aby przypisać do swojej zmiennej, możesz po prostu zrobić coś takiego:

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

Możesz również użyć funkcji o wartościach skalarnych:

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

Wtedy możesz po prostu to zrobić

Declare @MyDate datetime;
SET @MyDate = (Select dbo.TestDateFunction());
SELECT @MyDate;
CodeCaptain
źródło