[运行SQL Server 2008 SP3]
我有一个查询导致smalldatetime
类型溢出。然而,由于我构建查询的方式,这种情况(理论上)永远不会发生——逻辑应该在执行导致溢出的DATEADD()
之前很久就知道真值。
以下是WHERE子句的相关部分:
TimeIn >= '1/8/1950' AND TimeIn < '1/9/1950' AND
DATEADD(week, DATEDIFF(week, '1/8/1950', '9/14/2014'), TimeIn) >= '9/14/2014'
这非常有效——除非TimeIn(smalldatetime
)>=10/1/2014,否则它将溢出smalldatetime空间。但为什么DATEADD()
会被执行呢?如果日期是10/1/14,则应永远不要执行。。。但确实如此。
WHERE
标准的各部分并没有按照定义的顺序执行,这会阻止DATEADD()
的执行,这不是SQL Server的工作方式。
当我用硬编码的有问题的日期运行您的查询时,我实际上并没有看到错误,但解决这个问题的一种方法是使用CASE
表达式:
TimeIn >= '1/8/1950' AND TimeIn < '1/9/1950'
AND CASE WHEN TimeIn >= '1950-01-08' AND TimeIn < '1950-01-09'
THEN DATEADD(week, DATEDIFF(week, '1/8/1950', '9/14/2014'), TimeIn)
END >= '2014-09-14'