Хранимая процедура вызывает несколько хранимых процедур - PullRequest
0 голосов
/ 11 ноября 2009

При вызове нескольких хранимых процедур для одной хранимой процедуры это правильный или лучший способ сделать это в SQL Server 2008?

CREATE PROCEDURE [dbo].[DoStuff]
AS
BEGIN
    SET NOCOUNT ON;
    declare @result int
    BEGIN TRANSACTION
        BEGIN
            EXECUTE @result = dbo.UpdateTHIS @ID = 1            
            IF @result != 0
                ROLLBACK
            ELSE 
                EXECUTE @result = dbo.UpdateTHAT @ID = 21               
                IF @result != 0
                    ROLLBACK
                ELSE
                    EXECUTE @result = dbo.UpdateANOTEHR @ID = 15
                    IF @result != 0
                        ROLLBACK
                    ELSE
                        COMMIT
                        SELECT @result 
        END             
END

Ответы [ 3 ]

5 голосов
/ 11 ноября 2009

Я настоятельно рекомендую использовать блоки TRY / CATCH и RAISERROR вместо @@ ERROR / @ проверки результатов. У меня есть запись в блоге, которая показывает, как правильно использовать транзакции и блоки TRY / CATCH, включая вложенные транзакции, чтобы отменить только неудачный вызов процедуры, чтобы клиент мог возобновить другой путь и продолжить транзакцию, если он чувствует, что: Обработка исключений и вложенные транзакции .

Вы не согласны с режимом возврата процедур. UpdateTHIS и UpdateTHAT возвращают 0/1 в качестве возвращаемого значения, тогда как оболочка DoStuff возвращает в качестве набора результатов (SELECT). Это означает, что вы не можете написать DoMoreStuff, который вызывает DoStuff, потому что он должен использовать INSERT ... EXEC для захвата результата, и вы быстро обнаружите, что INSERT ... EXEC не может вкладываться. Вместо этого я рекомендую использовать RETURN @result для согласованности.

У меня также есть несвязанная похвала, которая является просто элементом стиля: я считаю, что длинные IF ... ELSE IF ... ELSE IF ... ELSE IF ... блоки трудно читать и следовать. Я всегда обнаруживал, что выражение, аналогичное выражению DO ... BREAK ... BREAK ... BREAK ... WHILE (FALSE) легче читать. В T-SQL нет конструкции DO ... WHILE, поэтому вместо нее нужно использовать WHILE ...:

BEGIN TRANSACTION
WHILE (1=1)
BEGIN
  EXECUTE @result = dbo.UpdateTHIS @ID = 1;         
  IF @result != 0
  BEGIN
     ROLLBACK;
     BREAK;
  END 

  EXECUTE @result = dbo.UpdateTHAT @ID = 21             
  IF @result != 0
  BEGIN
     ROLLBACK;
     BREAK;
  END

  ...

  COMMIT;
  BREAK;
END

Опять же, это не важно, так как это просто стиль форматирования кода, но это предложение, если вы согласны с тем, что в результате получается код, который легче читать.

1 голос
/ 11 ноября 2009

Вложенные if и not / nested if отличаются . Откат отката транзакции, но продолжайте. У меня были некоторые явные команды RETURN, чтобы гарантировать и сделать очевидным, когда и где вы хотите, чтобы код выходил из хранимой процедуры.

0 голосов
/ 11 ноября 2009

ИМХО, я не думаю, что вызов других хранимых процедур из одного хранимого процесса - очень хорошая идея. Если есть ошибка, потребуется много человеческих часов, чтобы выяснить, где произошла ошибка. В некоторых случаях другой разработчик может изменить хранимый процесс, не сказав никому в команде. Количество вещей, которые могут пойти не так, слишком велико.

Лучше всего написать все ваши sql в одном большом хранимом процессе.

Отредактировано: Это также зависит от того, насколько большим будет ваш хранимый процесс.

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