Como essa sintaxe funciona? {fn CurDate ()} ou {fn Now ()} etc

19

Recentemente, estive examinando alguns procedimentos armazenados bastante antigos que foram escritos para o SQL Server 2005 e notei algo que não entendo. Parece ser algum tipo de chamada de função.

Uma amostra:

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

Isto irá exibir todas as linhas de sys.objectsque têm um create_dateantes de 24 horas atrás.

Se eu exibir o plano de execução para esta consulta, vejo que {fn Now()}é substituído getdate()pelo Mecanismo de Banco de Dados:

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

Claramente, o uso {fn Now()}é muito mais obtuso do que GetDate(). Eu, pelo menos, evitarei essa sintaxe como a praga, pois não é documentada.

Max Vernon
fonte

Respostas:

25

É a sintaxe de escape do ODBC, e o mecanismo sabe qual é sua própria implementação e a troca, como você viu no plano de execução. Há também outras coisas, como:

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

Veja a documentação aqui , aqui , aqui e o mais importante aqui . Mas, por favor, não investigue e aprenda sobre essa sintaxe; IMHO, você deve usar a sintaxe nativa na maior parte e fingir que nunca ouviu falar desse material.

Também recomendo fortemente contra a getdate()-1abreviação, principalmente se você estiver voltando e atualizando o código antigo. Seja explícito e use DATEADD, pois a abreviação implícita não funciona com novos tipos. Por exemplo, tente:

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

Resultado:

Msg 206, Nível 16, Estado 2, Linha 2
Tipo de operando em conflito: a data é incompatível com int

Enquanto estiver lá, adicione também os pontos e vírgulas, se você realmente quiser proteger seu código daqui a dez anos.

Aaron Bertrand
fonte
Essa sintaxe de escape também é suportada pelo JDBC.
A_horse_with_no_name