【问题标题】:When an error stops execution in SQL Server?SQL Server 中的错误何时停止执行?
【发布时间】:2012-02-20 15:38:08
【问题描述】:

如果我执行这批:

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'.

我强迫两个错误: - 第一个:PRINT 1/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'.

并停止批处理的执行

它们之间有什么不同?我在哪里可以了解停止执行和不停止执行的那些?

非常感谢!!

【问题讨论】:

    标签: sql-server execution


    【解决方案1】:

    由于第一个错误是除以零错误,this behavior depends on your ARITHABORT, ARITHIGNORE and ANSI_WARNINGS settings.

    来自文章:

    这三个 SET 命令为您提供了非常精细的控制 一小部分错误。当被零除或发生溢出时, 有不少于四个选择。

    • 根本不执行任何操作,结果为 NULL – 当 ARITHIGNORE 为 ON 时。
    • 警告消息,结果为 NULL - 当所有都关闭时。
    • 语句终止 - 当 ANSI_WARNINGS 为 ON 时。
    • 批量中止 - 当 ARITHABORT 为 ON 且 ANSI_WARNINGS 为 OFF 时。

    至于哪些错误会停止执行,哪些不会,请refer to the same article

    【讨论】:

      【解决方案2】:

      确保正确处理所有错误的最简单方法是使用 TRY/CATCH

      没有这个,不同的错误可能是语句、范围或批处理中止,具体取决于 ARITHxx、ANSI_WARNINGS 和 XACT_ABORT 等设置。这在"Error Handling in 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”的对象。

      【讨论】:

      • @PankajGarg:如果你最终进入 CATCH 块,我会回滚。我也使用 SET XACT_ABORT ON 无论如何都会回滚
      【解决方案3】:

      我在哪里可以了解那些停止执行的方法

      您可以使用异常处理


      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
      

      【讨论】:

        猜你喜欢
        • 2010-10-14
        • 1970-01-01
        • 2018-03-15
        • 1970-01-01
        • 2014-11-29
        • 2014-01-20
        • 2019-05-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多