Luk*_*uke 8 sql database transactions sql-server-2005 try-catch
我创建了一个存储过程来运行许多命令来修改数据.如果一切顺利,我只想提交事务.我是通过以下方式使用try-catch块来实现这一点的(其中我真实的CATCH块使用RAISERROR来返回错误消息):
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
Run Code Online (Sandbox Code Playgroud)
这是我想要的方式.例如,如果我将MyBitColumn设置为'b'而不是1,则会捕获错误,控制流到CATCH,并且不会提交事务.
我注意到的一个问题是,如果数据库中不存在Table3,那么它会出错(无效的对象名称),但CATCH块永远不会被执行,并且事务保持打开状态.
我想处理这个问题来处理数据库被修改的任何(远程)可能性(或者在正确添加此存储过程的情况下发生的事情,但其中一个表没有).
我该如何处理这些错误案例?
-谢谢你的帮助.
Mit*_*eat 11
在脚本开始时使用SET XACT_ABORT
SET XACT_ABORT ON
Run Code Online (Sandbox Code Playgroud)
当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
Run Code Online (Sandbox Code Playgroud)
错误未被捕获,控制从TRY ... CATCH构造传递到下一个更高级别.
归档时间: |
|
查看次数: |
6101 次 |
最近记录: |