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

时间:2011-10-21 07:42:41

标签: sql sql-server tsql sql-server-2008

考虑:

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;
一切正常。尽管the documentation表明call是正确的语法。

为什么EXECCALL没有时才会有效?

3 个答案:

答案 0 :(得分:16)

Yup .. CALL是一个可从ODBC驱动程序使用的构造/语法,如文档所示。

T-SQL文档中没有CALL的引用,只有EXEC

它不起作用,因为它不是T-SQL。

答案 1 :(得分:5)

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

最终结果是,如果您愿意,可以使用CALL从客户端调用顶级存储过程,但如果该过程调用其他过程,则必须使用EXEC

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

答案 2 :(得分:2)

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

所以像这样的声明会执行:

create procedure spwho
as begin
    call sp_who2
end
go

exec spwho

不幸的是,即使创建了该过程,它也不会产生任何结果(但它也不会产生任何错误或警告)。

因此,在这种情况下,CALL语句不会在MSSQL中产生错误,但无论如何应该永远不会使用,因为它不起作用