Хранимая процедура - вызывающий порядок выполнения

У меня есть хранимая процедура, которая сама называет список других хранимых процедур в порядке:

CREATE PROCEDURE [dbo].[prSuperProc]

AS
BEGIN
    EXEC [dbo].[prProc1] 
    EXEC [dbo].[prProc2] 
    EXEC [dbo].[prProc3]
    --etc
END

Однако у меня иногда есть некоторые странные результаты в моих таблицах, сгенерированных prProc2, который зависит от результатов, сгенерированных prProc1. Если я вручную выполняю prProc1, prProc2, prProc3 в порядке затем все прекрасно. Кажется, что, когда я выполняю процедуру верхнего уровня, что Proc2 выполняется, прежде чем Proc1 завершил и передал свои результаты дб. Это не всегда идет не так, как надо, но это, кажется, идет не так, как надо, когда Proc1 имеет долгое время выполнения (в этом случае ~10s).

Как я изменяю prSuperProc, таким образом, что каждая процедура только выполняется, после того как предыдущая процедура завершила и фиксировала? Транзакции?

Редактирование для дополнительной детали:

Существует таблица в моем дб, который имеет столбец, который является пустым по умолчанию. prProc1 выполняет ряд операторов обновления на этой таблице для заполнения этого столбца. prProc2 затем вставляет сводные данные во вторичную таблицу на основе значений в этом столбце.

То, когда я выполняю супер процедуру, что я (иногда) вижу, является первой таблицей, вычислили результаты правильно prProc1, но prProc2 генерировал результаты, как будто столбец был всеми, аннулирует. Если я затем вручную выполняю prProc2, сводные данные сгенерирован правильно.

5
задан gbn 2 May 2010 в 12:16
поделиться

3 ответа

Proc2 будет не запускаться перед Proc1: это просто. SQL будет выполняться один за другим, но никогда не выходит из строя.

Вы можете профилировать это, используя шаблон TSQL_SPs

У вас есть, например, 2 выполнения процедуры оболочки?

4
ответ дан 14 December 2019 в 04:33
поделиться

У меня была та же проблема (в то время продукт поддерживался), и я исправил ее. вынимая самый внешний процесс и выполняя самый верхний процесс. Затем этот процесс будет выполнять процесс, зависящий от него, и так далее. Это заноза в заднице, но это работает.

HTH

2
ответ дан 14 December 2019 в 04:33
поделиться

Для каждого вызова prSuperProc они будут выполняться последовательно: 1, затем следующий, затем следующий. Однако, если несколько пользователей вызывают prSuperProc , тогда вы будете иметь чередование выполнения prProc1-prProc2 + prProc3 пользователя 1 и prProc1-prProc2 + prProc3 пользователя 2.

что может быть примерно таким:

user1 calls prSuperProc
user1          prProc1 is called
user2 calls prSuperProc
user1          prProc2 is called
user2          prProc1 is called
user1          prProc3 is called
user2          prProc2 is called
user2          prProc3 is called

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

EDIT {{1 }} вы можете попробовать следующее, чтобы решить проблему:

CREATE PROCEDURE [dbo].[prSuperProc]

AS
BEGIN TRY
    BEGIN TRANSACTION
    EXEC [dbo].[prProc1] 
    EXEC [dbo].[prProc2] 
    EXEC [dbo].[prProc3]
    --etc
    COMMIT
END TRY
BEGIN CATCH
    IF XACT_STATE()!=0
    BEGIN
        ROLLBACK TRANSACTION
    END

    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage


    --will echo back the complete original error message
    DECLARE @ErrorMessage nvarchar(400), @ErrorNumber int, @ErrorSeverity int, @ErrorState int, @ErrorLine int
    SELECT @ErrorMessage = N'Error %d, Line %d, Message: '+ERROR_MESSAGE(),@ErrorNumber = ERROR_NUMBER(),@ErrorSeverity = ERROR_SEVERITY(),@ErrorState = ERROR_STATE(),@ErrorLine = ERROR_LINE()
    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorNumber,@ErrorLine)

END CATCH
GO

используя транзакцию для всего, она попытается заблокировать одновременную работу всех пользователей с одними и теми же данными. Использование TRY-CATCH попытается отловить любые ошибки, которые могут произойти в одной процедуре, и предотвратить запуск следующих.

2
ответ дан 14 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: