SQL Server 中的错误何时停止执行?

Posted

技术标签:

【中文标题】SQL Server 中的错误何时停止执行?【英文标题】:When an error stops execution in 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'.

并停止批处理的执行

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

非常感谢!!

【问题讨论】:

【参考方案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

【讨论】:

以上是关于SQL Server 中的错误何时停止执行?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 SQL Server 中的错误 26?

SP 执行时 SQL Server 2008 中的 QUOTED IDENTIFIER 错误

可能错误 - SQL Server 中的错误

何时怎样开启 MySql 日志?

Sql Server 中的 @@ERROR

SSIS 包中的 C# 脚本在 SQL Server 表的数据执行过程中挂起,没有明确的错误消息