【问题标题】:SQL only a throw inside if statementSQL 只有一个 throw inside if 语句
【发布时间】:2013-08-05 08:00:53
【问题描述】:

我正在向几个存储过程添加一些验证,并且需要检查一些变量是否不为空(它们在存储过程的早期填充)。

我一直在尝试在 if 语句中添加一个“抛出”,如下所示:

IF (@val is null)
BEGIN
    THROW 50001, 'Custom text', 1
END

这会导致“throw”出现语法错误,因为它在 throw 之前在 if 语句中查找其他代码,但我只需要它在 if 语句中执行 throw。

我需要使存储过程尽可能的轻量,以使其尽可能快地执行。

有人有什么想法吗?

【问题讨论】:

标签: sql sql-server if-statement throw


【解决方案1】:

出现语法错误是因为上一个语句尚未终止。其他答案也可以,但为了做到这一点,您可以在 THROW 之前抛出一个分号,或者养成用分号终止所有语句的习惯。

IF (@val is null)
BEGIN
    ;THROW 50001, 'Custom text', 1
END

IF (@val is null)
BEGIN;
    THROW 50001, 'Custom text', 1;
END;

您可能已经注意到:

IF (@val is null)
    THROW 50001, 'Custom text', 1

... 也可以工作,这是因为 SQL Server 知道 IF 语句之后的下一件事总是一个新的 T-SQL 语句。

或许值得注意的是,微软表示未来的 T-SQL 语言将要求在每条语句后使用分号,所以我的建议是现在就开始养成这个习惯。

【讨论】:

  • 这应该是答案。
  • 那个语法肯定看起来很奇怪 BEGIN;这里的陈述 END;为什么可以终止 BEGIN !?
  • @joedotnot 可能怪微软? :-) 也许当 throw 是唯一的语句时,最好省略 BEGIN/END,而当 throw 之前使用其他语句时,BEGIN 之后的分号是不必要的。
  • 类似于 WITH 语句来创建公用表表达式:前面的语句也需要终止才能使 WITH 工作:P
  • 显然,它认为END TRY BEGIN CATCH 是一个单一的语句。它不允许在END TRY 之后使用分号,并显示错误“expecting END CATCH”。但是您可以将整个事情终止为END TRY BEGIN CATCH;
【解决方案2】:

如果这是针对 SQL Server 的,intellisense 语法高亮不喜欢它,但代码应该可以正常编译和运行。当然,由于它是单个语句,因此您根本不需要 BEGIN...END 块:

IF (@val is null) THROW 50001, 'Custom text', 1

【讨论】:

  • 在使用 readyroll 构建时,我仍然会得到“错误的语法接近抛出”(它在 ssms 中编译和工作正确。
【解决方案3】:
DECLARE @val NVARCHAR(50) = NULL
IF @val is null

    RAISERROR('Custom text', 16,16)

针对不同级别 检查

http://msdn.microsoft.com/en-us/library/ms164086.aspx

【讨论】:

  • 看起来readyroll软件不喜欢throw,编译时报错,但使用RAISERROR可以正常工作。
  • RAISERROR 不应再在新代码中使用,因为它将在未来停止使用。
  • @NReilingh 2019 年结束,但我们仍在使用 RAISERROR
猜你喜欢
  • 2010-09-21
  • 2018-02-06
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 2015-02-07
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
相关资源
最近更新 更多