【问题标题】:SQL Server - semicolon before THROWSQL Server - THROW 前的分号
【发布时间】:2016-11-14 19:47:49
【问题描述】:

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

【问题讨论】:

  • 如果你是THROW 之后的一些代码而不是; 会发生什么?
  • @mcNets 你的意思是像here这样的东西吗?
  • 可能它正在尝试回滚到名为 throw 的保存点。
  • @lad2025 是的,有点奇怪
  • 根据 MSDN 文档:备注 THROW 语句之前的语句必须后跟分号 (;) 语句终止符。 msdn.microsoft.com/en-us/library/ee677615.aspx

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


【解决方案1】:

如果您更改代码,它实际上会引发错误。

BEGIN TRY
  -- some code
  SELECT 1/0;
END TRY
BEGIN CATCH
   -- some code
   ROLLBACK TRANSACTION
   THROW;

END CATCH

你看

Msg 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之前需要一个分号的原因。

【讨论】:

    猜你喜欢
    • 2012-03-29
    • 2013-05-16
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2017-05-08
    相关资源
    最近更新 更多