2011-10-21 7 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; 

が、私は

EXEC LowerCityDiscounts 'Cleveland', 5; 
に物事を変更する場合にのみ、しかし

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

を生成します

すべて正常に動作します。これにもかかわらず、callが正しい構文であることを示すthe documentationがあります。

なぜEXECCALLの場合に機能しますか?

+0

リンクされたドキュメントはODBCドライバに関連しています。つまり、 'CALL'はODBC構造です。あなたはODBCを使用していますか? –

+0

1つはtsqlキーワード、もう1つは基本的に – Peter

+0

です。@KierenJohnstone:私はアプリケーション内でODBCを使用していますが、SQL Server Management Studioの中でテストしています。 –

答えて

13

です。CALLは、ドキュメントに示されているように、ODBCドライバから使用できる構文/構文です。

CALLへの参照はありません。EXECのみです。

T-SQLでないため動作しません。

4

T-SQL言語はODBCエスケープシーケンスを認識しません。 EXECは、ストアドプロシージャの呼び出しに使用できる唯一のコマンドです。 ODBCエスケープシーケンスは、クライアントサイドライブラリ(ODBC、OLE DB、ADO、ADO.NETなど)によって解釈され、実行前にその場で実際のT-SQL構文に変換されます。

最後に、CALLを使用してクライアントから最上位のストアドプロシージャを呼び出すことができますが、そのプロシージャが他のものを呼び出す場合はEXECを使用する必要があります。

同じ原則が日付/時刻リテラルエスケープシーケンスに適用されます。

+0

'{CALL [Foo]}'は、SQL Serverが見る前に 'EXEC'としてODBCドライバによって書き換えられます。しかし、日付/時刻リテラルエスケープシーケンスでは同じことは当てはまりません。SQL Serverは、私が決定できる限り、それらをネイティブに理解します。 –

+0

@マルティン:ありがとう、毎日何か新しいことを学ぶ。 :-) –

2

MSSQLがストアドプロシージャ内のCALLステートメントを受け入れる問題(データベースの移行中)を実行しましたが、SQL Management Studioは文句を言いますが、クエリ自体は正常に実行されます。

だから、このような文が実行されない:

create procedure spwho 
as begin 
    call sp_who2 
end 
go 

exec spwho 

を不幸にプロシージャが作成されていても、それがどんな結果を生成しません(ただし、どちらも、それはエラーまたは警告を生成しないん)。

このような場合、CALLステートメントはMSSQLでエラーを生成しませんが、とにかくは使用されません。

関連する問題