2009-10-22 9 views
0

Vous avez un problème étrange a créé un peu proc stocké qui doivent exécuter deux autres procs stockées pour obtenir des valeurs avant d'exécuter l'instruction select principal voir ci-dessous,SQL Stored Proc exécution Sélectionnez avant gettting valeurs d'autres procs

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[usp_get_ApplicationUserServiceRoles] 
    @UserId int, 
    @ApplicationName varchar(50), 
    @ServiceName varchar(50) 
AS 
BEGIN 
    ----------------------------------------- 
    SET NOCOUNT ON 
    ----------------------------------------- 
    DECLARE @ApplicationId INT 
    exec @ApplicationId = dbo.usp_get_AppIdFromName @ApplicationName 
    DECLARE @ServiceId INT 
    exec @ServiceId = dbo.usp_get_ServiceIdFromName @ServiceName 

    SELECT 
    [RoleName] 
    FROM 
    [ServiceRoles] s 
    INNER JOIN 
    [ApplicationUserServiceRoles] r 
    ON 
    s.ServiceRoleId = r.ServiceRoleId 
    INNER JOIN 
    [ApplicationServices] p 
    ON 
    s.ServiceId = p.ServiceId 
    WHERE 
    r.UserId = @UserID 
    AND 
    r.ApplicationId = @ApplicationId 
    AND 
    s.ServiceId = @ServiceId   
END 

Lorsque j'exécute ce proc stocké, il me renvoie les deux valeurs des deux procs avec ce proc mais pas la valeur de sélection réelle. Toutefois, lorsque j'exécute l'instruction select seule avec les valeurs renvoyées par le procs secondaire, elle renvoie les données correctes.

Une idée de ce qui se passe, est l'instruction select qui s'exécute avant les deux processus stockés secondaires afin que l'instruction select n'ait pas les bonnes valeurs?

Exécution dans SQL 2005

Répondre

3

La seule façon de capturer l'ensemble de résultats d'une procédure stockée est INSERT ... EXEC:

declare @applicationId int; 
declare @tableApplicationId table (ApplicationId ind); 
insert into @tableApplicationId 
exec dbo.usp_get_AppIdFromName @ApplicationName; 
select @applicationId = ApplicationId from @tableApplicationId; 

Vous voudrez peut-être envisager de changer dbo.usp_get_AppIdFromName en fonction au lieu, ou une procédure qui retourne @ applicationId en tant que paramètre OUTPUT.

INSERT ... EXEC a toutes sortes de problèmes d'effets secondaires, comme des problèmes de nidification:

+0

Merci pour votre aide j'ai transformé les deux sub procs en fonctions et ça fonctionne bien, merci encore. – Jon

+0

Pas tout à fait vrai, un proc stocké renvoie un entier. Idéal pour les états d'erreur de retour, etc., mais peut également renvoyer une valeur entière de la même manière qu'une fonction. Utile où la 'fonction' doit écrire dans la base de données. – MatBailie

3

Une procédure stockée retourne un numéro indiquant l'état d'exécution de la procédure stockée. Pour capturer la sortie de l'instruction select, vous devrez utiliser INSERT ... EXECUTE (voir here pour plus de détails)

Ce qui se passe dans votre cas est que chaque sous-procédure s'exécute mais votre procédure principale échoue. Vérifiez votre fenêtre de sortie, il devrait vous dire l'erreur.

+0

Un grand merci pour la perspicacité – Jon

1

Si votre "sous" procédures stockées sont juste retour d'un seul valeur, il est préférable d'utiliser les paramètres de sortie, comme suit:

. 
. 
DECLARE @ApplicationId INT 
exec dbo.usp_get_AppIdFromName @ApplicationName, @ApplicationId OUTPUT 
. 
. 

Et le sous-proceduure devrait ressembler à:

CREATE PROCEDURE dbo.usp_get_AppIdFromName 
    @ApplicationName varchar(50) 
    ,@ApplicationId int OUTPUT 

AS 
BEGIN 

    -- Adjust as necessary 
    SELECT @ApplicationId = ApplicationId 
    from MyApplicationTable 
    where Name = @ApplicationName 

END 
RETURN 0 

(Notez que, dans votre structure originale,

exec @ApplicationId = dbo.usp_get_AppIdFromName @ApplicationName 

@ApplicationId sera affecté la valeur de l'instruction de retour qui, à mon par exemple, sera toujours 0. Il est préférable de réserver cette valeur pour renvoyer l'état de cet appel de procédure - c'est-à-dire, at-il fonctionné ou non.)

0

J'utiliserais plutôt deux appels de fonction. Il y a de fortes chances que ces procs stockés s'appellent eslewhere et si vous les modifiez avec les paramètres de sortie, alors quelque chose d'autre va se casser.

Questions connexes