我注意到存储过程可以作为
执行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
有助于消除歧义
答案 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)时,它们才是强制性的。