执行存储过程的不同方法的错误

Error in different methods of executing stored procedure

我注意到存储过程可以执行为

EXEC myProc;

以及

myProc;

假设myProc是一个没有参数的存储过程。

当我尝试一个一个地执行它们时,一切正常。但是一起执行

EXEC myProc;
myProc;

我收到这个错误:

Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'myProc'.

这里似乎有什么错误?我尝试使用和不使用 ;。没有 ;

EXEC myProc
myProc

它会认为我正在尝试将第二个 myProc 作为参数传递给第一个过程 myProc,但出现错误

Msg 8146, Level 16, State 1, Procedure myProc, Line 0
Procedure myProchas no parameters and arguments were supplied.

更多信息:

myProc;
EXEC myProc;

myProc
EXEC myProc

将执行,尽管编辑器会在第一个 myProc 调用 (incorrect syntax near myProc) 发出语法错误信号,如果我在它之前放置一个 GO,它就会消失。此外,它不会尝试猜测第二个 EXEC myProc 与第一个 myProc 调用的参数有任何关系,我想这是因为 EXEC 有助于消除歧义

单独引用存储过程名称时,即

sp_who2

SQL 服务器将根据它理解的命令(即当前数据库中的过程,或系统数据库中常见的共享过程)进行检查。但是,此语法允许多个非引号单词,例如:

sp_who2 active

为了使 T-SQL 语言明确无误,当您在一个批次中有多个命令动词时,您需要将它们分开,例如使用 EXEC 或其他合适的分隔符。否则你的意思是将第二个命令作为参数传递给第一个命令,还是你的意思是两个命令? SQL 服务器将允许以下内容,正如您已经明确指出的那样:

sp_who2
EXEC sp_who2

那会很好。这不会:

sp_who2
sp_who2

因为你的意思不明确

 EXEC sp_who2 'sp_who2'

EXEC sp_who2
EXEC sp_who2

其他示例是像 'MERGE INTO' 这样的语句,出于同样的原因,在批处理中的任何前面的语句之后需要分号或其他终止符,以避免语法歧义。

根据 SQL 服务器联机丛书参考 (https://msdn.microsoft.com/en-us/library/ms188332.aspx):

You do not have to specify the EXECUTE keyword when executing modules if the statement is the first one in a batch.

编辑:

让我们检查一下您问题中的各个批次。

这批成功:

EXEC myProc;

此批处理成功,因为它是批处理中的第一条语句,因此 EXECUTE 关键字是可选的:

myProc;

该批处理导致语法错误,因为该批处理中的第二条语句缺少 EXECUTE 关键字; EXECUTE 只能从第一条语句中省略。即使存在语法错误,正确使用语句终止符至少可以帮助 T-SQL 解析器理解您的意图。

EXEC myProc;
myProc;

此批处理因提供的参数错误而失败。第一个语句缺少语句终止符,第二个语句缺少 EXECUTE 关键字。这些错误的组合导致第二个过程名称被解释为批处理中第一个也是唯一一个执行语句的参数:

EXEC myProc
myProc

本次批处理成功,因为EXECUTE关键字对于批处理中的第一个procEXECUTE是可选的,后续的EXECUTE语句指定了该关键字。此批处理有或没有语句终止符都没有歧义:

myProc;
EXEC myProc;

这批也成功了,因为EXECUTE关键字对于批中的第一个proc EXECUTE是可选的,后面的EXECUTE语句指定了关键字。 T-SQL 解析器在这里足够宽松,可以识别 EXEC 引入了一个新语句,因此后续的 EXEC 关键字和 proc 名称不会被解释为第一个 EXECUTE:

的参数
myProc
EXEC myProc

我想补充一点,不推荐使用分号语句终止符的语法。老实说,我不希望分号在相当长的一段时间内成为强制性的。在当今世界,只有当下一条语句是新引入的 T-SQL 语句(例如 WITH)时,它们才是强制性的。