2009-10-22 61 views
0

流汗值之前,有一个奇怪的问题产生了一点存储过程,其需要执行其他几个存储特效的执行主select语句见下文之前得到一些值,SQL存储过程执行选择从其他特效

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 

当我运行这个存储的proc时,它返回两个proc函数中的两个值,但不是实际的选择值。但是,当我运行select语句自己的值辅助存储过程返回它返回正确的数据。

任何想法是怎么回事,是在两个辅助存储过程之前运行的select语句,所以select语句没有得到正确的值?

在SQL 2005

回答

3

捕捉到结果集的存储过程的唯一方法是INSERT ... EXEC:

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

你可能要考虑改变dbo.usp_get_AppIdFromName成函数来代替,或者返回过程@ applicationId作为OUTPUT参数。

INSERT ... EXEC拥有所有种类的副作用问题,如筑巢的问题:

+0

感谢您的帮助,我将两个子过程转换为函数并且工作正常,再次感谢。 – Jon 2009-10-22 17:04:56

+0

不完全如此,一个存储过程确实返回一个整数。返回错误状态等的理想选择,但也可以像函数一样返回一个整数值。在'函数'需要写入数据库的地方很有用。 – MatBailie 2009-10-24 22:42:47

3

存储过程运行,则返回一个数字,表示该存储过程的执行状态。为了捕获select语句的输出,你必须使用INSERT ... EXECUTE(详见here

你的情况会发生什么情况是每个子程序都执行但是你的主程序失败。检查你的输出窗口,它应该告诉你错误。

+0

非常感谢您的深入了解 – Jon 2009-10-22 17:04:23

1

如果你的 “子” 存储过程只是返回一个单一值,您最好使用输出参数,如下所示:

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

和子proceduure应该是这个样子:

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 

(需要注意的是,在原来的结构中,

exec @ApplicationId = dbo.usp_get_AppIdFromName @ApplicationName 

@ApplicationId将被分配RETURN语句的值,在我例如,将始终为0.最好保留此值以返回该过程调用的状态 - 即是否工作。)

0

我会使用两个函数调用。机会是这些存储过程称为eslewhere,如果你用输出参数修改它们,那么别的东西就会中断。