有一个奇怪的问题创建了一个小的存储过程,需要在执行主select语句之前执行一些其他存储过程来获取一些值,见下文,
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返回两个过程中的两个值,但不是实际的选择值。但是,当我自己运行select语句时,辅助存储过程返回的值会返回正确的数据。
知道发生了什么,是否在两个辅助存储过程之前运行了select语句,因此select语句没有得到正确的值?
在SQL 2005中运行
答案 0 :(得分:3)
存储过程返回一个数字,指示存储过程的执行状态。为了捕获select语句的输出,你必须使用INSERT ... EXECUTE(详见here)
在您的情况下会发生的是每个子过程都会执行但主程序失败。检查输出窗口,它应该告诉你错误。
答案 1 :(得分: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有各种副作用问题,比如嵌套问题:
答案 2 :(得分:1)
如果你的“子”存储过程只返回一个值,你最好使用输出参数,如下所示:
.
.
DECLARE @ApplicationId INT
exec dbo.usp_get_AppIdFromName @ApplicationName, @ApplicationId OUTPUT
.
.
子程序看起来应该是这样的:
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.最好保留此值以返回该过程调用的状态 - 也就是说,它是否有效。)
答案 3 :(得分:0)
我会使用两个函数调用。这些存储过程可能被称为eslewhere,如果你用输出参数修改它们,那么其他东西就会破坏。