SQL Server Try/Catch、Begin/Tran、RaiseError、Loop 和 Return。正确的顺序是啥?
Posted
技术标签:
【中文标题】SQL Server Try/Catch、Begin/Tran、RaiseError、Loop 和 Return。正确的顺序是啥?【英文标题】:SQL Server Try/Catch, Begin/Tran, RaiseError, Loop, & Return. What's the right order?SQL Server Try/Catch、Begin/Tran、RaiseError、Loop 和 Return。正确的顺序是什么? 【发布时间】:2018-01-03 16:51:26 【问题描述】:我有以下程序。 (语法并不完美,只是想给大家一个想法)。
begin tran
begin try
while loop
some condition, if true
raiseerror('error', 16, 1)
end try
begin catch
if transaction > 0
rollback tran
select error message
end catch
if transaction > 0
commit tran
问题:
raise 错误会强制 catch 块吗?如果是这样,事务是否会完全回滚(对于循环的所有迭代)?
我希望#1这样,是否需要在回滚后添加“RETURN”?
我问这个问题是因为即使在迭代中出现一些错误之后,循环似乎仍在继续。
【问题讨论】:
首先要做的事......你不应该在几乎所有情况下都使用循环来修改数据。但是,当然,如果您发出回滚,它会回滚整个事务。如果您在每次通过循环时都在执行事务,那么您的事务范围将是循环的主体。您应该将您的提交放在循环之后作为“结束尝试”之前的最后一条语句。不需要用 if 语句包装它。 这很复杂。在不同的情况和上下文中,哪些语句可能失败以及正确的恢复步骤是不同的。例如,大多数 SQL 开发人员可能不知道COMMIT
可能会失败,但它可以。
@SeanLange 我曾经有过只有一些被回滚的时候——他们有docs.microsoft.com/en-us/sql/t-sql/statements/…是有原因的
@Rj。如果您正在寻找一种方法来完成拥有多个 try/catch 块的方法,所有这些块都包含在单个事务中,并且具有全有或全无规则(如果有任何失败,则将其全部回滚),请告诉我,就像我所做的那样那,并用基本的代码结构回答了一个关于SO的问题。
@Eli,是的,这就是我想要完成的。
【参考方案1】:
看看这个问题(你真的问过):SQL Server XACT_ABORT with exclusion
虽然问题略有不同,但它显示了如何完成您正在尝试做的事情的基本结构。
30 秒的运行过程如下:像您所做的那样使用 try/catch 块,并在您的过程结束时有一个名为“失败”的部分,所有捕获都将指向该部分。您可以在每个 catch 中为您的日志记录设置一条消息,或将错误传递给最终用户。
【讨论】:
以上是关于SQL Server Try/Catch、Begin/Tran、RaiseError、Loop 和 Return。正确的顺序是啥?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server Try/Catch、Begin/Tran、RaiseError、Loop 和 Return。正确的顺序是啥?