这个语法如何运作?{fn CurDate()}或{fn Now()}等


19

最近,我一直在浏览一些为SQL Server 2005编写的相当老的存储过程,并且发现一些我不理解的东西。它似乎是某种类型的函数调用。

一个样品:

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

这将显示所有行sys.objects有一个create_date前24小时前。

如果显示此查询的执行计划,{fn Now()}则会看到该计划已被getdate()数据库引擎替换:

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

显然,使用{fn Now()}远比钝GetDate()。我会避免像瘟疫这样的语法,因为它没有记录。

Answers:


25

它是ODBC转义语法,并且引擎知道自己的实现是什么,并将其换出,如您在执行计划中所看到的。还有其他事情,例如:

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

查看文档在这里这里这里,最重要的这里。但是,请不要研究和了解这种语法。恕我直言,您应该在大多数情况下使用本机语法,并假装自己从未听说过这些东西。

我也强烈建议您不要使用getdate()-1速记,特别是如果您要返回并更新旧代码时。要明确并使用DATEADD,因为隐式速记不适用于新类型。例如,尝试:

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

结果:

消息206,级别16,状态2,第2行,
操作数类型冲突:日期与int不兼容

如果您确实想在十年后保护自己的代码,则可以在其中添加分号。


JDBC也支持此转义语法。
a_horse_with_no_name
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.