Comment affecter un résultat exécutable à une variable SQL?

108

Comment attribuez-vous le résultat d'un appel exécutable à une variable dans SQL? J'ai un proc stocké appelé up_GetBusinessDay, qui renvoie une seule date.

Pouvez-vous faire quelque chose comme ça:

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

Réponses:

97

J'utilise toujours la valeur de retour pour renvoyer le statut d'erreur. Si vous avez besoin de renvoyer une valeur, j'utiliserais un paramètre de sortie.

exemple de procédure stockée, avec un paramètre 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

appel à la procédure stockée, avec un paramètre OUTPUT:

DECLARE @OutputParameter  datetime
       ,@ReturnValue      int

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

PRODUCTION:

0
2010-01-01 00:00:00.000
KM.
la source
10
En utilisant un paramètre OUTPUT, vous pouvez renvoyer n'importe quel type de données, la valeur RETURN d'une procédure stockée ne peut être qu'un entier.
KM.
2
Juste une remarque, les paramètres OUTPUT qui sont déclarés avec une valeur n'ont pas besoin d'être passés. Cela signifie que si vous modifiez un SP existant, vous pouvez le faire en toute sécurité sans risquer de casser quoi que ce soit. par exemple, @ Param3 datetime = '1900-01-01' OUTPUT.
Morvael
55

Cela fonctionnera si vous souhaitez simplement renvoyer un entier:

DECLARE @ResultForPos INT 
EXEC @ResultForPos = storedprocedureName 'InputParameter'
SELECT @ResultForPos
Siddhesh Bondre
la source
13
-1 Cela ne renverra qu'un entier. L'OP veut renvoyer une date. La réponse acceptée par @KM. est la bonne réponse, car elle utilise OUTPUT au lieu de RETURN.
Code Maverick
4
En fait, cela fonctionne. L'exemple sur la façon d'obtenir un entier qui est retourné, vous pouvez faire la même chose pour tous les autres types (je n'ai pas vérifié si la table est possible, mais je pense que oui.) Je viens de l'essayer pour nvarchar (50).
Mzn
2
@Mzn "vous pouvez faire la même chose pour tous les autres types" , ne fonctionne certainement pas avec UNIQUEIDENTIFIER.
James
1
@James Pourquoi? En quoi le type de données uniqueidentifier est-il différent? Les procédures stockées ne peuvent pas renvoyer des identifiants uniques?
Mzn le
3
@Mzn UNIQUEIDENTIFIERn'était qu'un exemple, RETURNest conçu pour fonctionner uniquement avec des valeurs entières, voir la documentation . La méthode recommandée pour obtenir d'autres données d'un SP est de retourner un jeu de résultats ou d'utiliserOUTPUT
James
34
declare @EventId int

CREATE TABLE #EventId (EventId int)

insert into #EventId exec rptInputEventId

set @EventId = (select * from #EventId)

drop table #EventId 
AZ Tchad
la source
3
en fait, la seule façon de travailler décrite ici à part changer la signature du proc stocké
Michael Sander
2
Utilisé également pour une date, lorsque le Sproc sous-jacent n'a pas non plus de paramètre de sortie. (Le sproc sous-jacent avait un autre Exec à l'intérieur de SQL dynamique)
Jeff Beagley
3
@MichaelSander Tout à fait raison, toutes les autres solutions ne répondent pas correctement à la question des OP. Le seul moyen est une table temporaire qui contient les résultats.
SQL Police
3
Seul moyen qui fonctionne ici sans nécessiter de modifications du proc, ce que je ne peux pas faire dans mon cas. +1
DLeh
Vous pouvez également utiliser une variable de table à la place d'une table temporaire.
erreur du
6

À partir de la documentation (en supposant que vous utilisez SQL-Server):

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

Alors oui, cela devrait fonctionner de cette façon.

Peter Lang
la source
8
dans l'exemple de l'OP, ils veulent renvoyer une date, les procédures stockées ne peuvent RETOURNER qu'une valeur entière à une procédure appelante ou à une application.
KM.
0

J'avais la même question. Bien qu'il y ait de bonnes réponses ici, j'ai décidé de créer une fonction table. Avec une fonction table (ou scalaire), vous n'avez pas à modifier votre proc stocké. J'ai simplement fait une sélection à partir de la fonction table. Notez que le paramètre (MyParameter est facultatif).

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

Pour affecter à votre variable, vous pouvez simplement faire quelque chose comme:

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

Vous pouvez également utiliser une fonction à valeur scalaire:

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

Ensuite, vous pouvez simplement faire

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