Jak działa ta składnia? {fn CurDate ()} lub {fn Now ()} itp

19

Ostatnio przeglądałem dość stare procedury składowane napisane dla SQL Server 2005 i zauważyłem coś, czego nie rozumiem. Wydaje się, że to jakiś rodzaj wywołania funkcji.

Próbka:

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

Spowoduje to wyświetlenie wszystkich wierszy z sys.objects, które mają działanie create_datewcześniej niż 24 dni temu.

Jeśli wyświetlę plan wykonania dla tego zapytania, widzę, że {fn Now()}jest on zastąpiony getdate()przez Aparat baz danych:

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

Oczywiście używanie {fn Now()}jest znacznie bardziej tępe niż GetDate(). I na przykład uniknę tej składni jak zarazy, ponieważ jest ona nieudokumentowana.

Max Vernon
źródło

Odpowiedzi:

25

Jest to składnia ucieczki ODBC, a silnik wie, co to jest jego własna implementacja, i zamienia ją, jak widzieliście w planie wykonania. Istnieją również inne rzeczy, takie jak:

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

Zobacz dokumentację tutaj , tutaj , tutaj , a co najważniejsze tutaj . Ale proszę, nie badaj i nie poznaj tej składni; IMHO powinieneś w większości używać natywnej składni i udawać, że nigdy nie słyszałeś o tych rzeczach.

Również zdecydowanie odradzam getdate()-1stenografowanie, szczególnie jeśli wracasz i aktualizujesz stary kod. Wyraźnie i używaj DATEADD, ponieważ niejawny skrót nie działa z nowymi typami. Na przykład spróbuj:

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

Wynik:

Msg 206, Level 16, State 2, Line 2
Operand type clash: data jest niezgodna z int

Gdy tam jesteś, równie dobrze możesz dodać średniki, jeśli naprawdę chcesz chronić swój kod za 10 lat.

Aaron Bertrand
źródło
Ta składnia ucieczki jest również obsługiwana przez JDBC.
a_horse_w_no_name