Подтвердить что ты не робот

В чем разница между CALL и EXEC в T-SQL?

Рассмотрим:

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 является правильным синтаксисом.

Почему EXEC работает, когда call не работает?

4b9b3361

Ответ 1

Yup.. CALL - это конструктор/синтаксис, используемый из драйвера ODBC, как указывает ваша документация.

В документации T-SQL нет ссылки на CALL, только EXEC.

Это не работает, потому что это не T-SQL.

Ответ 2

Язык T-SQL не распознает escape-последовательности ODBC; EXEC - единственная команда, доступная для вызова хранимой процедуры. Управляющие последовательности ODBC интерпретируются библиотеками на стороне клиента (например, ODBC, OLE DB, ADO, ADO.NET) и транслируются на реальный синтаксис T-SQL на лету перед выполнением.

Конечный результат: вы можете вызвать свою хранимую процедуру верхнего уровня у клиента, используя CALL, если хотите, но если эта процедура вызывает других, она должна использовать EXEC.

Тот же принцип применяется для последовательных escape-последовательностей даты/времени.

Ответ 3

Я столкнулся с проблемой (при миграции баз данных), что MSSQL будет принимать инструкцию CALL в хранимой процедуре - SQL Management Studio жалуется, но сам запрос выполняется успешно.

Итак, такой оператор выполняет:

create procedure spwho
as begin
    call sp_who2
end
go

exec spwho

К сожалению, несмотря на то, что процедура создана, она не дает никаких результатов (но также она не вызывает никаких ошибок или предупреждений).

Итак, в таких случаях оператор CALL не будет вызывать ошибки в MSSQL, но в любом случае никогда не должен использоваться, так как он не работает.