T-SQL中CALL和EXEC有什么区别?

20

考虑:

CREATE PROCEDURE LowerCityDiscounts @city VARCHAR(45), @decrease DECIMAL(10,2) AS
BEGIN
    BEGIN TRANSACTION;
    UPDATE Customers SET discnt = discnt - @decrease
    WHERE Customers.city = @city;

    UPDATE Customers SET discnt = 0
    WHERE Customers.city = @city AND discnt < 0
    COMMIT;
END;

我尝试使用以下方式调用此过程:

CALL LowerCityDiscounts 'Cleveland', 5;

但这只会产生

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

然而,如果我将事情改为

EXEC LowerCityDiscounts 'Cleveland', 5;

一切都正常工作。尽管文档说明call是正确的语法。

为什么CALL不起作用,而EXEC可以?


这个链接的文档与ODBC驱动程序相关,即CALL是ODBC结构。你正在使用ODBC吗? - Kieren Johnstone
一个是T-SQL关键字,另一个则不是。 - Peter
@KierenJohnstone:嗯,我在应用程序中使用ODBC,但我正在SQL Server Management Studio中测试一些东西。 - Billy ONeal
好的,根据我的回答,你找到的文档是关于ODBC驱动程序,而不是SQL Server的Transact-SQL语言。 - Kieren Johnstone
3个回答

19

是的,在ODBC驱动程序中可以使用CALL构造/语法,正如您的文档所示。

T-SQL文档中没有关于CALL的参考,只有EXEC

它不能正常工作,因为它不是T-SQL。


5

T-SQL语言不支持ODBC转义序列; EXEC是唯一可用于调用存储过程的命令。ODBC转义序列由客户端库(例如ODBC、OLE DB、ADO、ADO.NET)解释,并在执行之前即时转换为真实的T-SQL语法。

结果是,如果您想要从客户端调用顶层存储过程,则可以使用CALL,但如果该过程调用其他过程,则必须使用EXEC

日期/时间文字转义序列也适用相同的原则。


在ODBC驱动程序将{ CALL [Foo] }发送给SQL Server之前,它会被重写为EXEC。然而,对于日期/时间文字转义序列似乎并非如此。据我所知,SQL Server本地理解这些序列。 - Martin Smith

2

我遇到了一个问题(在迁移数据库时),MSSQL可以接受存储过程中的CALL语句,虽然SQL Management Studio会抱怨,但查询本身成功执行。

因此,像这样的语句确实会执行:

create procedure spwho
as begin
    call sp_who2
end
go

exec spwho

不幸的是,尽管已经创建了该过程,但它并没有产生任何结果(但它也没有产生任何错误或警告)。

因此,在这种情况下,CALL语句在MSSQL中不会产生错误,但绝不能使用,因为它不起作用


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