最近我一直在查看为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中在24小时之前具有create_date的所有行.
如果我显示此查询的执行计划,我会看到数据库引擎将{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()更加迟钝.我一个人会像瘟疫一样避免这种语法,因为它没有记录.
解决方法
它是ODBC转义语法,引擎知道自己的实现是什么,并将其交换出来,正如您在执行计划中看到的那样.还有其他的东西,例如:
SELECT {fn curdate()},{ts '2016-05-24 15:19:36'},-- not vulnerable to SET LANGUAGE! {guid 'D08891B4-BC25-4C7C-BAEF-3B756055AC6E'};
请参阅文档here,here,here,最重要的是here.但请不要调查并了解此语法;恕我直言,你应该使用原生语法大部分,并假装你从来没有听说过这些东西.
我也强烈建议不要使用getdate() – 1速记,特别是如果你要返回并更新旧代码.显式并使用DATEADD,因为隐式速记不适用于新类型.例如,尝试:
DECLARE @d DATE = GETDATE(); SELECT @d - 1;
结果:
Msg 206,Level 16,State 2,Line 2
Operand type clash: date is incompatible with int