T-SQL try ... catch и несколько пакетов (2 begin ... end, если ... else) - PullRequest
4 голосов
/ 07 марта 2012

Я пытаюсь понять, как попробуй ... поймать конструкция работает в T-SQL.

Итак, я прочитал статью на MSDN: http://msdn.microsoft.com/en-us/library/ms175976.aspx

Я немного запутался с этим утверждением: Конструкция TRY… CATCH не может охватывать несколько партий. Конструкция TRY… CATCH не может охватывать несколько блоков операторов Transact-SQL. Например, конструкция TRY… CATCH не может охватывать два блока BEGIN… END операторов Transact-SQL и не может охватывать конструкцию IF… ELSE.

Он говорит, что try ... catch не может охватывать 2 блока BEGIN ... END и не может охватывать конструкцию IF ... ELSE.

Однако, я попробовал это, и это работает! (как на 2005, так и на 2008 год)

Может кто-нибудь объяснить, почему? Похоже на ошибку в MSDN.

Посмотрите на мой тестовый скрипт:

print 'start'
begin transaction test_tran
begin try
    -- first begin ... end
    begin
        -- some statements
        print 'begin ... end - #1'
    end
    -- second begin ... end
    begin
        print 'begin ... end - #2'
        -- statement with error
        select 1/0 -- division by zero
    end
    print 'end of try'
end try
begin catch
    print 'catch'
    goto RollbackTran
end catch

-- commit
print 'commit'
commit transaction test_tran

-- rollback
RollbackTran:
    BEGIN
        print 'rollback'
        WHILE @@TRANCOUNT > 0 
        begin
            ROLLBACK TRANSACTION test_tran
            print 'actual rollback'
        end
    END

Результаты:

start
begin ... end - #1
begin ... end - #2

(0 row(s) affected)
catch
rollback
actual rollback

Работает (2 начало ... конец блока)! Но MSDN говорит, что не должно. То же самое для IF ... ELSE.

Может кто-нибудь объяснить это?

1 Ответ

6 голосов
/ 07 марта 2012

Пакет T-SQL чаще всего обозначается GO-статутом.Они говорят, что вы не можете сделать это:

BEGIN TRY

    PRINT 'statement 1'

    GO -- Cannot have a GO to end batch inside of a TRY / CATCH

    PRINT 'statement 2'

END TRY
BEGIN CATCH

    PRINT 'Catch Block'

END CATCH

Аналогично, вы не можете:

IF (1 = 1)
BEGIN
   BEGIN TRY

     PRINT 'test'

END -- Cannot END a block that began prior to the TRY / CATCH

   END TRY
   BEGIN CATCH

     PRINT 'Catch block'

   END CATCH

, и вы не можете сделать это:

IF (1 = 1)
    BEGIN TRY

        PRINT 'statement 1'

ELSE -- Cannot do ELSE for an IF that started prior to the TRY / CATCH
        PRINT 'statement 2'

    END TRY
    BEGIN CATCH

        PRINT 'Catch Block'

    END CATCH
...