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

时间:2015-07-26 22:09:34

标签: sql-server stored-procedures exec

我注意到存储过程可以作为

执行
EXEC myProc;

以及

myProc;

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

当我尝试逐个执行它们时,工作正常。但是一起执行它们

EXEC myProc;
myProc;

我收到此错误:

  

Msg 102,Level 15,State 1,Line 3
  'myProc'附近的语法不正确。

这里的错误似乎是什么?我尝试了没有;。没有;

EXEC myProc
myProc

它会认为我试图将第二个myProc作为参数传递给第一个程序myProc而我收到错误

  

Msg 8146,Level 16,State 1,Procedure myProc,Line 0
  过程myProchas没有提供参数和参数。

更多信息:

myProc;
EXEC myProc;

myProc
EXEC myProc

将执行,尽管编辑器会在第一次myProc调用(incorrect syntax near myProc)时发出语法错误信号,如果我在其前加GO,它将会消失。此外,它不会试图猜测第二个EXEC myProc是否有任何事情可以作为第一个myProc调用的参数,我想这是因为EXEC有助于消除歧义

2 个答案:

答案 0 :(得分:4)

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

sp_who2

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

sp_who2 active

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

sp_who2
EXEC sp_who2

这样可以正常工作。但这不会:

sp_who2
sp_who2

因为你的意思是否含糊不清

 EXEC sp_who2 'sp_who2'

EXEC sp_who2
EXEC sp_who2

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

答案 1 :(得分:2)

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

  

执行模块时不必指定EXECUTE关键字   如果该陈述是批次中的第一个。

修改

让我们检查你问题中的各个批次。

此批次成功:

EXEC myProc;

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

myProc;

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

EXEC myProc;
myProc;

此批处理失败,并提供参数错误。第一个语句缺少语句终止符,第二个语句缺少EXECUTE关键字。这些错误的组合导致第二个proc名称被解释为批处理中第一个和唯一的execute语句的参数:

EXEC myProc
myProc

此批处理成功,因为EXECUTE关键字对于批处理中的第一个proc EXECUTE是可选的,后续EXECUTE语句指定关键字。无论是否有语句终止符,此批处理都不明确:

myProc;
EXEC myProc;

此批处理也成功,因为EXECUTE关键字对于批处理中的第一个proc EXECUTE是可选的,后续EXECUTE语句指定关键字。 T-SQL解析器在这里很松懈,认识到EXEC引入了一个新语句,因此后续的EXEC关键字和proc名称不会被解释为第一个EXECUTE的参数:

myProc
EXEC myProc

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