为什么同样的尝试catch块有两个不同的结果

时间:2013-07-03 23:38:04

标签: sql sql-server tsql

我想在CATCH块中遇到错误时回滚TRY块中的所有语句:

BEGIN TRY
    begin transaction

    create table t3(a int )
    insert into t3 values(1)
    insert into t3 values(1,2)  --error occur
    insert into t3 values(3)

END TRY
BEGIN CATCH
    --just take care of rollback
    IF @@TRANCOUNT <> 0
    BEGIN
        PRINT 'in catch,ROLLING BACK';
        ROLLBACK
    END
END CATCH
go

首先,由于CATCH块中的PRINT有效,因此会捕获错误。但是,经过多次来回更改后,错误似乎不再出现在CATCH中,因为不再打印。

no printing out

因此,我打开一个新查询并执行相同的操作。这个时间错误可以再次被捕获!!

printing out

抱歉大图片

1 个答案:

答案 0 :(得分:2)

当您在管理工作室等工具中运行此代码时,您的交易将保留在您的SPID中(分配给查询窗口)。

因此,不一致的reult 问题是因为您没有关闭所有代码路径上的事务(假设没有达到回滚),您的事务在下次仍然处于活动状态你运行脚本。

如果您在脚本的开头添加IF @@TRANCOUNT <> 0 rollback transaction,您将获得一致的输出。

另请注意,try catch块并不意味着在语句编译级别捕获错误。

如果您将错误替换为除以零(例如print 1 / 0),则捕获将正常工作。

MSDN

  

当CATCH块与TRY ... CATCH构造处于相同的执行级别时,它们不会处理以下类型的错误:

     

编译阻止批处理的错误,例如语法错误   运行

     
      
  • 语句级重新编译期间发生的错误,例如对象名称解析
  •   
  • 由于延迟名称解析而在编译后发生的错误。
  •