Wie funktioniert diese Syntax? {fn CurDate ()} oder {fn Now ()} etc

19

Vor kurzem habe ich einige ziemlich alte gespeicherte Prozeduren durchgesehen, die für SQL Server 2005 geschrieben wurden, und mir ist etwas aufgefallen, das ich nicht verstehe. Es scheint sich um einen Funktionsaufruf zu handeln.

Eine Probe:

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

Hiermit werden alle Zeilen angezeigt sys.objects, die create_datevor 24 Stunden erstellt wurden.

Wenn ich den Ausführungsplan für diese Abfrage anzeige, {fn Now()}wird dieser getdate()durch das Datenbankmodul ersetzt:

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

Es ist klar, dass die Verwendung {fn Now()}weitaus stumpfer ist als GetDate(). Ich jedenfalls werde diese Syntax wie die Pest vermeiden, da sie nicht dokumentiert ist.

Max Vernon
quelle

Antworten:

25

Es handelt sich um eine ODBC-Escape-Syntax, und die Engine weiß, was ihre eigene Implementierung ist, und tauscht sie aus, wie Sie im Ausführungsplan gesehen haben. Es gibt auch andere Dinge, wie zum Beispiel:

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

Sehen Sie die Dokumentation hier , hier , hier und vor allem hier . Aber bitte untersuchen Sie diese Syntax nicht und lernen Sie sie nicht kennen. IMHO sollten Sie die native Syntax zum größten Teil verwenden und so tun, als hätten Sie noch nie von diesem Zeug gehört.

Ich empfehle auch dringend, die getdate()-1Abkürzung zu verwenden, insbesondere, wenn Sie zurückgehen und alten Code aktualisieren. Seien Sie explizit und verwenden Sie DATEADD, da die implizite Abkürzung bei neuen Typen nicht funktioniert. Versuchen Sie zum Beispiel:

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

Ergebnis:

Meldung 206, Ebene 16,
Status 2, Zeile 2 Kollision vom Typ Operand: Datum ist nicht kompatibel mit int

Während Sie dort sind, können Sie auch die Semikolons hinzufügen, wenn Sie Ihren Code wirklich 10 Jahre in der Zukunft schützen möchten.

Aaron Bertrand
quelle
Diese Escape-Syntax wird auch von JDBC unterstützt.
a_horse_with_no_name