Когда ошибка останавливает выполнение в SQL Server? - PullRequest
5 голосов
/ 20 февраля 2012

Если я выполняю эту партию:

begin transaction
    PRINT 'start'
    PRINT 1/0
    PRINT 'continue'
    drop table dbo.tblPrueba
    select * from dbo.tblPrueba
    PRINT 'finish'
rollback transaction

Результат такой:

start
Msg 8134, Level 16, State 1, Line 3
Divide by zero error encountered.
continue
Msg 208, Level 16, State 1, Line 6
Invalid object name 'dbo.tblPrueba'.

Я вынуждаю две ошибки: - первая : PRINT1/0 (которая генерирует эту ошибку:

Msg 8134, Level 16, State 1, Line 3
Divide by zero error encountered.

) и продолжить выполнение пакета

- второй:

drop table dbo.tblPrueba
select * from dbo.tblPrueba

, который генерирует эту ошибку:

Msg 208, Level 16, State 1, Line 6
Invalid object name 'dbo.tblPrueba'.

и останавливает выполнение пакета

Чем они отличаются?Где я могу узнать тех, кто останавливает выполнение, и тех, кто не делает?

Большое спасибо !!

Ответы [ 3 ]

10 голосов
/ 20 февраля 2012

Поскольку первая ошибка - это ошибка деления на ноль, это поведение зависит от настроек ARITHABORT, ARITHIGNORE и ANSI_WARNINGS.

Из статьи:

Эти три команды SET дают вам очень детальное управление для очень небольшой набор ошибок. Когда деление на ноль или переполнение происходит, Есть не менее четырех вариантов.

  • Никаких действий вообще, результат NULL - когда ARITHIGNORE включен.
  • Предупреждающее сообщение, результат равен NULL - когда все выключены.
  • Завершение оператора - когда ANSI_WARNINGS включен.
  • Пакетный аборт - когда ARITHABORT включен, а ANSI_WARNINGS выключен.

Что касается того, какие ошибки останавливают выполнение, а какие нет, пожалуйста, см. Ту же статью .

4 голосов
/ 20 февраля 2012

Самый простой способ обеспечить правильную обработку всех ошибок - использовать TRY / CATCH

Без этого могут быть разные ошибки: оператор, область действия или прерывание пакета в зависимости от таких параметров, как ARITHxx, ANSI_WARNINGS и XACT_ABORT. Это демонстрируется и обсуждается на «Обработка ошибок в SQL 2000»

Вы можете увидеть другие (параметры SET не изменены) с этим

CREATE TABLE dbo.tblPrueba (gbn int);
GO

BEGIN TRY

    begin transaction
        PRINT 'start'
        PRINT 1/0
        PRINT 'continue'
        drop table dbo.tblPrueba
        select * from dbo.tblPrueba
        PRINT 'finish'
    rollback transaction

END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE();
    IF XACT_STATE() <> 0 rollback transaction
END CATCH

Если я запускаю это дважды, я получаю это, потому что DROP никогда не выполняется

Сообщение 2714, Уровень 16, Состояние 6, Строка 1
В базе данных уже есть объект с именем tblPrueba.

1 голос
/ 21 февраля 2012

Где я могу узнать тех, кто останавливает выполнение

Вы можете использовать обработку исключений


Begin try
  begin transaction
    PRINT 'start'
    PRINT 1/0
    PRINT 'continue'
    create table #t
    ( 
       id int
    )
    drop table #t
    select * from #t
    PRINT 'finish'
  rollback transaction
End Try

Begin Catch
   if( XACT_STATE() == 1)
     Rollback Tran
End Catch

Вы можете использовать Set XACT_ABORT ON, как показано ниже.

Set XACT_ABORT ON
begin transaction
    PRINT 'start'
    PRINT 1/0
    PRINT 'continue'
    create table #t
    ( 
       id int
    )
    drop table #t
    select * from #t
    PRINT 'finish'
rollback transaction
...