SQL Stored Proc Executing Выберите перед получением значений из других процедур - PullRequest
0 голосов
/ 22 октября 2009

Получил странную проблему, создав небольшой сохраненный процесс, который должен выполнить несколько других сохраненных процедур, чтобы получить некоторые значения перед выполнением основного оператора выбора, см. Ниже,

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

Когда я запускаю этот сохраненный процесс, он возвращает мне два значения из двух процессов с этим процессом, но не фактическое значение выбора. Однако, когда я сам запускаю оператор select со значениями, которые возвращают вторичные хранимые процедуры, он возвращает правильные данные.

Есть идеи, что происходит, оператор SELECT выполняется перед двумя вторичными сохраненными процессами, поэтому оператор SELECT не имеет правильных значений?

Запуск в SQL 2005

Ответы [ 4 ]

3 голосов
/ 22 октября 2009

Единственный способ получить набор результатов хранимой процедуры - это 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 имеет всевозможные побочные эффекты, такие как проблемы с вложением:

3 голосов
/ 22 октября 2009

Хранимая процедура возвращает число, указывающее статус выполнения хранимой процедуры. Чтобы захватить выходные данные оператора select, вы должны будете использовать INSERT ... EXECUTE (подробности см. здесь )

В вашем случае происходит то, что каждая подпроцедура выполняется, но ваша основная процедура не выполняется. Проверьте окно вывода, оно должно сообщить вам об ошибке.

1 голос
/ 22 октября 2009

Если ваши «вспомогательные» хранимые процедуры только возвращают одно значение, лучше всего использовать выходные параметры, например:

.
.
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. Лучше зарезервировать это значение для возврата состояния вызова этой процедуры - то есть, сработало или нет .)

0 голосов
/ 25 октября 2009

Вместо этого я бы использовал два вызова функций. Скорее всего, эти хранимые процедуры называются eslewhere, и если вы измените их с помощью выходных параметров, то что-то еще сломается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...