SQL:Try/Catch 在尝试访问找不到的表时未捕获错误



我创建了一个存储过程,它运行许多命令来修改数据。我只想在一切成功的情况下提交事务。我通过以下方式使用try-catch块来实现这一点(在实际操作中,我的catch块使用RAISEROR返回错误消息):

BEGIN TRY
  BEGIN TRANSACTION
  UPDATE Table1 SET MyVarcharColumn = 'test'
  UPDATE Table2 SET MyBitColumn = 1
  UPDATE Table3 SET MyIntColumn = 42
  COMMIT TRANSACTION
END TRY
CATCH
  ROLLBACK TRANSACTION
END CATCH

这是我想要的方式。例如,如果我将MyBitColumn设置为"b"而不是1,则会捕获错误,控制流到CATCH,并且不会提交事务。

我注意到的一个问题是,如果数据库中不存在Table3,那么它就会出错(对象名称无效),但CATCH块永远不会执行,事务仍然处于打开状态。

我想处理这个问题,以处理数据库被修改的任何(远程)可能性(或者在正确添加了这个存储过程但其中一个表没有添加的情况下发生的事情)。

我应该如何处理这些错误情况?

-谢谢你的帮助。

在脚本开始时使用SET XACT_ABORT

SET XACT_ABORT ON

当SET XACT_ABORT为ON时,如果Transact-SQL语句引发运行时错误,整个事务被终止并回滚。

我认为这是不可能的:

以下类型的错误不由CATCH块处理:它们发生在与TRY…CATCH构造相同的执行级别:

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

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

参考。

以下示例显示了对象名称解析错误由SELECT语句生成的未被TRY…CATCH捕获构造,但在相同SELECT时被CATCH块捕获语句在存储过程中执行。

USE AdventureWorks2012;
GO
BEGIN TRY
    -- Table does not exist; object name resolution
    -- error not caught.
    SELECT * FROM NonexistentTable;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH

错误未被捕获,控制超出TRY…CATCH建设到下一个更高的水平。

EXECUTE ('SELECT * FROM NonexistentTable');

相关内容

最新更新