SQL仅在if语句中使用一次

41

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

我一直在尝试像下面这样在if语句中添加一个"throw":

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

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

我需要尽可能地减少存储过程的负担,以使其尽可能快地执行。

有人有任何想法吗?


1
THROW是SQL Server 2012的一个功能。 - Ocaso Protal
3个回答

77

语法错误出现是因为前面的语句没有被终止。其他答案也可以工作,但如果想要以这种方式完成,您可以在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语言将要求在每个语句后使用分号,因此我建议现在开始养成这个习惯。


14
这应该就是答案。 - Davos
2
那个语法看起来确实很奇怪 BEGIN; 在这里编写语句 END; 为什么在终止 BEGIN 的时候可以这样做呢!? - joedotnot
@joedotnot 可能要怪微软? :-) 或许当 throw 是唯一的语句时,省略 BEGIN/END 更可取;而当在 throw 之前使用其他语句时,BEGIN 后的分号是不必要的。 - NReilingh
类似于使用WITH语句创建公共表达式,前一个语句也需要被终止才能使WITH正常工作。 :P - iceheaven31
1
显然,它认为END TRY BEGIN CATCH是一个单独的语句。它不允许在END TRY之后加分号,并显示错误“期望END CATCH”。但你可以将整个语句终止为END TRY BEGIN CATCH; - Triynko

3
如果这是针对SQL Server的话,智能感知语法高亮器可能不喜欢它,但代码应该可以编译和运行。当然,由于它是一个单个语句,你根本不需要使用BEGIN...END块:
IF (@val is null) THROW 50001, 'Custom text', 1

1
当使用readyroll构建时,我仍然会收到“throw附近的语法不正确”的错误(在ssms中编译并正常工作)。 - Edmund G

-2

看起来 ReadyRoll 软件不支持 throw,编译时会出错,但使用 RAISERROR 则可以正常工作。 - Edmund G
6
RAISERROR不应在新代码中使用,因为它将在未来被停用。 - NReilingh
@NReilingh,虽然已经是2019年底了,但我们仍在使用RAISERROR。 - Sql Programmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接