2011-10-21 9 views
13

xem xét:Sự khác nhau giữa CALL và EXEC trong T-SQL là gì?

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; 

Tôi cố gắng để gọi thủ tục này với:

CALL LowerCityDiscounts 'Cleveland', 5; 

nhưng điều này chỉ sản xuất

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

Tuy nhiên, nếu tôi thay đổi mọi thứ để

EXEC LowerCityDiscounts 'Cleveland', 5; 

mọi thứ đều hoạt động tốt. Điều này mặc dù rằng the documentation nói rằng call là cú pháp đúng.

Tại sao EXEC hoạt động khi CALL không?

+0

Tài liệu được liên kết liên quan đến trình điều khiển ODBC, tức là 'CALL' là một cấu trúc ODBC. Bạn đang sử dụng ODBC? –

+0

Một là từ khóa tsql, cái kia không phải là cơ bản là – Peter

+0

@KierenJohnstone: Vâng, tôi đang sử dụng ODBC bên trong ứng dụng, nhưng tôi đang thử nghiệm mọi thứ bên trong SQL Server Management Studio. –

Trả lời

13

Yup .. CALL là một cấu trúc/cú pháp có thể sử dụng được từ trình điều khiển ODBC, như tài liệu của bạn cho biết.

Không có tham chiếu nào trong tài liệu T-SQL tới CALL, chỉ EXEC.

Nó không hoạt động vì nó không phải là T-SQL.

4

Ngôn ngữ T-SQL không nhận ra các chuỗi thoát ODBC; EXEC là lệnh duy nhất có sẵn để gọi thủ tục được lưu trữ. Các trình tự thoát ODBC được giải thích bởi các thư viện phía máy khách (ví dụ: ODBC, OLE DB, ADO, ADO.NET) và được dịch sang cú pháp T-SQL thực trước khi thực thi.

Kết quả cuối cùng là, bạn có thể gọi thủ tục lưu trữ cấp cao nhất từ ​​máy khách bằng cách sử dụng CALL nếu muốn, nhưng nếu thủ tục đó gọi cho người khác, thì phải sử dụng EXEC.

Nguyên tắc tương tự cũng áp dụng cho chuỗi thoát ngày/giờ.

+0

'{CALL [Foo]}' được viết lại bởi trình điều khiển ODBC là 'EXEC' trước khi SQL Server nhìn thấy nó . Điều tương tự dường như không đúng đối với trình tự thoát ngày tháng theo thời gian.SQL Server thực sự hiểu chúng theo như tôi có thể xác định. –

+0

@Martin: Cảm ơn vì điều đó, hãy tìm hiểu điều gì đó mới mẻ mỗi ngày. :-) –

2

Tôi chạy qua một vấn đề (trong khi di chuyển cơ sở dữ liệu) MSSQL sẽ chấp nhận tuyên bố CALL trong thủ tục được lưu trữ - SQL Management Studio phàn nàn nhưng chính truy vấn được thực thi thành công.

Vì vậy, một tuyên bố như thế này không thực hiện:

create procedure spwho 
as begin 
    call sp_who2 
end 
go 

exec spwho 

Đáng tiếc là mặc dù các thủ tục được tạo ra, nó không tạo ra bất kỳ kết quả (nhưng không phải nó tạo ra bất kỳ lỗi hoặc cảnh báo).

Vì vậy, trong trường hợp như vậy, câu lệnh CALL sẽ không tạo ra lỗi trong MSSQL nhưng dù sao không bao giờ được sử dụng vì nó không hoạt động.