2009-10-22 47 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,如果你用輸出參數修改它們,那麼別的東西就會中斷。