我们知道用分号结束每个语句是一个很好的做法。假设我们有一些旧代码使用RAISERROR
来重新抛出异常,我们希望将其与THROW
交换。
来自:THROW
:
THROW 语句之前的语句必须后跟 分号(;)语句终止符。
仅使用ROLLBACK
:
BEGIN TRY
-- some code
SELECT 1;
END TRY
BEGIN CATCH
-- some code
ROLLBACK
THROW;
END CATCH
我们得到 Incorrect syntax near 'THROW'.
,这完全有效。
但是使用ROLLBACK TRANSACTION
可以不使用分号:
BEGIN TRY
-- some code
SELECT 1;
END TRY
BEGIN CATCH
-- some code
ROLLBACK TRANSACTION
THROW;
END CATCH
的 LiveDemo
最后使用ROLLBACK TRANSACTION @variable
:
DECLARE @TransactionName NVARCHAR(32) = 'MyTransactionName';
BEGIN TRY
-- some code
SELECT 1;
END TRY
BEGIN CATCH
-- some code
ROLLBACK TRANSACTION @TransactionName
THROW;
END CATCH
我们再次获得 Incorrect syntax near 'THROW'.
。
第二个例子的工作原理是否有任何特殊原因(向后兼容性/...)?
修改
Erland Sommarskog撰写了一篇很棒的文章: Using ;THROW
答案 0 :(得分:4)
如果您更改了代码,那么它实际上会抛出错误。
BEGIN TRY
-- some code
SELECT 1/0;
END TRY
BEGIN CATCH
-- some code
ROLLBACK TRANSACTION
THROW;
END CATCH
你看
消息3903,级别16,状态1,行7 ROLLBACK TRANSACTION请求 没有相应的BEGIN TRANSACTION。
它正在尝试回滚到名为THROW
的保存点。
这是有效的语法,但在上面的示例中在运行时失败,因为没有事务存在。如果您处于未结交易但没有此类保存点(如下所示)
BEGIN TRY
BEGIN TRAN
SELECT 1/0;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
THROW;
END CATCH
ROLLBACK
您会看到以下内容。
无法回滚。没有该名称的事务或保存点 找到。
这种模糊性可能是为什么在throw
之前存在对前一个分号的要求。