Bagaimana cara kerja sintaks ini? {fn CurDate ()} atau {fn Now ()} dll

19

Baru-baru ini saya telah mencari melalui beberapa prosedur tersimpan yang cukup lama yang ditulis untuk SQL Server 2005, dan saya perhatikan sesuatu yang saya tidak mengerti. Tampaknya ada beberapa jenis panggilan fungsi.

Sebuah sampel:

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

Ini akan menampilkan semua baris dari sys.objectsyang memiliki create_datesebelum 24 jam yang lalu.

Jika saya menampilkan rencana eksekusi untuk kueri ini, saya melihat bahwa {fn Now()}itu diganti dengan getdate()oleh Mesin Database:

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

Jelas, menggunakan {fn Now()}jauh lebih bodoh daripada GetDate(). I untuk satu akan menghindari sintaks ini seperti wabah karena tidak berdokumen.

Max Vernon
sumber

Jawaban:

25

Itu sintaks ODBC melarikan diri, dan mesin tahu apa implementasinya sendiri, dan menukarnya, seperti yang Anda lihat dalam rencana eksekusi. Ada juga hal-hal lain, seperti:

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

Lihat dokumentasi di sini , di sini , di sini , dan yang paling penting di sini . Tapi tolong jangan selidiki dan pelajari tentang sintaks ini; IMHO Anda harus menggunakan sintaksis asli untuk sebagian besar dan berpura-pura tidak pernah mendengar hal ini.

Saya juga sangat merekomendasikan terhadap getdate()-1steno, terutama, jika Anda kembali dan memperbarui kode lama. Jadilah eksplisit dan gunakan DATEADD, karena tulisan singkat tersirat tidak bekerja dengan tipe baru. Misalnya, coba:

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

Hasil:

Msg 206, Level 16, State 2, Line 2
Operan tipe clash: date tidak kompatibel dengan int

Saat Anda berada di sana, semoga menambahkan semi-titik dua juga jika Anda benar-benar ingin melindungi kode Anda 10 tahun ke depan.

Aaron Bertrand
sumber
Sintaks pelarian ini didukung oleh JDBC juga.
a_horse_with_no_name