SQL Server - THROW之前的分号

时间:2016-11-14 19:47:49

标签: sql sql-server tsql sql-server-2012

我们知道用分号结束每个语句是一个很好的做法。假设我们有一些旧代码使用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

1 个答案:

答案 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之前存在对前一个分号的要求。