2011-10-21 25 views
13

考慮:T-SQL中的CALL和EXEC有什麼區別?

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是正確的語法。

爲什麼EXEC工作時CALL不?

+0

鏈接的文檔涉及ODBC驅動程序,即'CALL'是一個ODBC結構。你正在使用ODBC? –

+0

一個是tsql關鍵字,另一個基本不是 – Peter

+0

@KierenJohnstone:嗯,我在應用程序內部使用ODBC,但是我正在測試SQL Server Management Studio中的東西。 –

回答

13

是的。CALL是一個可以從ODBC驅動程序使用的結構/語法,如文檔所示。

在T-SQL文檔中沒有提到CALL,只有EXEC

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

4

T-SQL語言不識別ODBC轉義序列; EXEC是唯一可用於調用存儲過程的命令。 ODBC轉義序列由客戶端庫(例如ODBC,OLE DB,ADO,ADO.NET)解釋,並在執行前即時轉換爲真正的T-SQL語法。

最終結果是,如果您願意,可以使用CALL從客戶端調用您的頂級存儲過程,但如果該過程調用其他客戶端,則必須使用EXEC

相同的原則適用於日期/時間字面義轉義序列。

+0

SQL Server在看到它之前,ODBC驅動程序將'{CALL [Foo]}'重寫爲EXEC 。儘管如此,日期/時間字面轉義序列似乎也不是這樣。據我所知,SQL Server本身就可以理解它們。 –

+0

@Martin:謝謝你,每天都要學習新的東西。 :-) –

2

我遇到了一個問題(在遷移數據庫時),MSSQL將在存儲過程中接受CALL語句--SQL Management Studio抱怨但查詢本身已成功執行。

所以像這樣的語句也執行:

create procedure spwho 
as begin 
    call sp_who2 
end 
go 

exec spwho 

不幸的是,即使在創建過程中,也不會產生任何結果(但它也不會產生任何錯誤或警告)。

因此,在這種情況下,CALL語句不會在MSSQL中產生錯誤,但無論如何不應該使用,因爲它不起作用