¿Cómo funciona esta sintaxis? {fn CurDate ()} o {fn Now ()} etc.

19

Recientemente, he estado revisando algunos procedimientos almacenados bastante antiguos que fueron escritos para SQL Server 2005, y he notado algo que no entiendo. Parece ser algún tipo de llamada de función.

Una muestra:

SELECT o.name, o.type_desc, o.create_date
FROM sys.objects o
WHERE o.create_date < {fn Now()} -1;

Esto mostrará todas las filas de las sys.objectsque tenían create_dateantes de hace 24 horas.

Si visualizo el plan de ejecución para esta consulta, veo que {fn Now()}es reemplazado getdate()por el Motor de base de datos:

SELECT [o].[name],[o].[type_desc],[o].[create_date] 
FROM [sys].[objects] [o] 
WHERE [o].[create_date]<(getdate()-@1)

Claramente, usar {fn Now()}es mucho más obtuso que GetDate(). Por mi parte, evitaré esta sintaxis como la peste, ya que no está documentada.

Max Vernon
fuente

Respuestas:

25

Es la sintaxis de escape de ODBC, y el motor sabe cuál es su propia implementación y la cambia, como ha visto en el plan de ejecución. También hay otras cosas, como:

SELECT {fn curdate()},
       {ts '2016-05-24 15:19:36'}, -- not vulnerable to SET LANGUAGE!
       {guid 'D08891B4-BC25-4C7C-BAEF-3B756055AC6E'};

Vea la documentación aquí , aquí , aquí , y lo más importante aquí . Pero por favor no investigue y aprenda sobre esta sintaxis; En mi humilde opinión, debe utilizar la sintaxis nativa en su mayor parte y pretender que nunca ha oído hablar de estas cosas.

También recomiendo encarecidamente la getdate()-1taquigrafía, especialmente si vas a volver y actualizar el código antiguo. Sea explícito y use DATEADD, ya que la taquigrafía implícita no funciona con tipos nuevos. Por ejemplo, intente:

DECLARE @d DATE = GETDATE();
SELECT @d - 1;

Resultado:

Mensaje 206, Nivel 16, Estado 2, Línea 2
Tipo de operando choque: la fecha es incompatible con int

Mientras esté allí, también puede agregar los punto y coma, si realmente desea proteger su código dentro de 10 años.

Aaron Bertrand
fuente
Esta sintaxis de escape también es compatible con JDBC.
a_horse_with_no_name