Comment fonctionne cette syntaxe? {fn CurDate ()} ou {fn Now ()} etc

19

Récemment, j'ai parcouru des procédures stockées assez anciennes qui ont été écrites pour SQL Server 2005, et j'ai remarqué quelque chose que je ne comprends pas. Il semble s'agir d'un certain type d'appel de fonction.

Un échantillon:

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

Cela affichera toutes les lignes sys.objectsqui ont un create_dateavant il y a 24 heures.

Si j'affiche le plan d'exécution de cette requête, je vois qu'il {fn Now()}est remplacé getdate()par le moteur de base de données:

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

De toute évidence, l'utilisation {fn Now()}est beaucoup plus obtuse que GetDate(). Pour ma part, j'éviterai cette syntaxe comme la peste car elle n'est pas documentée.

Max Vernon
la source

Réponses:

25

Il s'agit de la syntaxe d'échappement ODBC, et le moteur sait quelle est sa propre implémentation et la remplace, comme vous l'avez vu dans le plan d'exécution. Il y a aussi d'autres choses, telles que:

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

Voir la documentation ici , ici , ici et surtout ici . Mais s'il vous plaît, ne cherchez pas et ne vous renseignez pas sur cette syntaxe; À mon humble avis, vous devriez utiliser la syntaxe native pour la plupart et prétendre que vous n'avez jamais entendu parler de ce genre de choses.

Je recommande également fortement contre la getdate()-1sténographie, surtout si vous revenez en arrière et mettez à jour l'ancien code. Soyez explicite et utilisez DATEADD, car le raccourci implicite ne fonctionne pas avec les nouveaux types. Par exemple, essayez:

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

Résultat:

Msg 206, niveau 16, état 2, ligne 2
type d'opérande en conflit: la date est incompatible avec int

Pendant que vous y êtes, vous pouvez également ajouter les points-virgules, si vous voulez vraiment protéger votre code 10 ans dans le futur.

Aaron Bertrand
la source
Cette syntaxe d'échappement est également prise en charge par JDBC.
a_horse_with_no_name