如何尝试...抓住工作?

时间:2016-01-14 11:24:18

标签: sql-server tsql

我很好奇try...catch在某些情况下如何运作?

假设我有一些SQL代码要执行,如果前面的某些失败,我希望这些指令失败。

所以:

DECLARE @Sql1 VARCHAR(MAX) = 'Some sql statement',
        @Sql2 VARCHAR(MAX) = 'another sql statement',
        @Sql3 VARCHAR(MAX) = 'and another sql statement',

BEGIN TRY
       EXECUTE sp_executesql @Sql1
       EXECUTE sp_executesql @Sql2
       EXECUTE sp_executesql @Sql3
END TRY
BEGIN CATCH
       ....
END CATCH

如果@Sql1无法执行@Sql2@Sql3会发生什么情况?

如果@Sql2失败,我能以某种方式停止执行@Sql3@Sql1吗?

2 个答案:

答案 0 :(得分:2)

根据您的情况,

  1. 如果@ Sql1无法执行@ Sql2和@ Sql3会发生什么?

    如果@ Sql1失败,

    @ Sql2和@ Sql3将不会执行。

  2. 如果@ Sql1失败,我能以某种方式停止执行@ Sql2和@ Sql3吗?

    无需停止@ Sql2和@ Sql3,因为如果@ Sql1失败,那么您的控件将转移到catch块。所以你不需要明确地停止其余的陈述。

  3. 注意:

    如果TRY块中包含的代码中没有错误,则当TRY块中的最后一个语句完成运行时,控制将在关联的END CATCH语句之后立即传递给该语句。如果TRY块中包含的代码中存在错误,则控制将传递到关联的CATCH块中的第一个语句。如果END CATCH语句是存储过程或触发器中的最后一个语句,则控制权将传递回调用存储过程的语句或触发该触发器。

答案 1 :(得分:1)

试试这个,你可以通过用dml

替换下面的语句来获得更多信息
begin try
select 1--no error
select 1/0--error
select 1
select 1/0
select 1
end try
begin catch
raiserror('didvide by zero execption',16,1);
end catch

根据try catch的文档,错误控制将转移到catch块,这是你可以通过使用上述语句观察到的。

另外注意1正在打印,这意味着整个批次不会中止。您可以通过添加如下内容来处理此问题

begin try
begin tran
select 1
select 1/0
select 1
select 1/0
select 1
commit
end try
begin catch
rollback
raiserror('didvide by zero execption',16,1);
end catch

set xact_abort on
begin try
begin tran
select 1
select 1/0
select 1
select 1/0
select 1
commit
end try
begin catch

raiserror('didvide by zero execption',16,1);
end catch