2011-10-21 68 views
13

considerar:¿Cuál es la diferencia entre CALL y EXEC en 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; 

Traté de llamar a este procedimiento con:

CALL LowerCityDiscounts 'Cleveland', 5; 

pero esto sólo se produce

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

Sin embargo, si cambio de cosas que

EXEC LowerCityDiscounts 'Cleveland', 5; 

todo funciona bien Esto a pesar de que the documentation indicando que call es la sintaxis correcta.

¿Por qué EXEC funciona cuando CALL no?

+0

La documentación vinculada se refiere al controlador ODBC, es decir, 'CALL' es una construcción ODBC. ¿Estás usando ODBC? –

+0

Una es una palabra clave tsql, la otra no es básicamente – Peter

+0

@KierenJohnstone: Bueno, estoy usando ODBC dentro de la aplicación, pero estoy probando cosas dentro de SQL Server Management Studio. –

Respuesta

13

Sip .. CALL es una construcción/sintaxis utilizable a partir de un controlador ODBC, como indica la documentación.

No hay referencia en la documentación de T-SQL en CALL, solo EXEC.

No funciona porque no es T-SQL.

4

El lenguaje T-SQL no reconoce las secuencias de escape ODBC; EXEC es el único comando disponible para llamar a un procedimiento almacenado. Las secuencias de escape de ODBC son interpretadas por las bibliotecas del lado del cliente (por ejemplo, ODBC, OLE DB, ADO, ADO.NET) y traducidas a la sintaxis de T-SQL real sobre la marcha antes de la ejecución.

El resultado final es que puede llamar a su procedimiento almacenado de nivel superior desde el cliente utilizando CALL si lo desea, pero si ese procedimiento llama a otros, debe usar EXEC.

El mismo principio se aplica a las secuencias de escape de fecha/hora.

+0

'{CALL [Foo]}' es reescrito por el controlador ODBC como 'EXEC' antes de que SQL Server lo vea . Lo mismo no parece ser cierto para las secuencias de escape literales de fecha/hora.SQL Server no los entiende nativamente por lo que pude determinar. –

+0

@Martin: gracias por eso, aprende algo nuevo todos los días. :-) –

2

Me encontré con un problema (durante la migración de las bases de datos) que MSSQL aceptará la declaración CALL en un procedimiento almacenado: SQL Management Studio se queja pero la consulta se ejecuta correctamente.

lo tanto una declaración como esto ejecutar:

create procedure spwho 
as begin 
    call sp_who2 
end 
go 

exec spwho 

Desafortunadamente a pesar de que se crea el procedimiento, que no produce ningún resultado (pero tampoco produce ningún error o advertencia).

Por lo tanto, en casos como este, la sentencia CALL no producirá errores en MSSQL, pero de todos modos nunca debería usarse, ya que no funciona.

Cuestiones relacionadas