我有一个简单的CTE从表中提取日期 - 日期(ApptDateTime
)以YYYY-MM-DDZHH:mm:SS
格式存储。有些列有NULL值,所以我想忽略它们,以及任何不是真正的日期。
如果我这样做:
;WITH cte
AS
(SELECT
urn,
CONVERT(DATETIME, ApptDateTime) AS ApptDateTime
FROM data
WHERE ISDATE(ApptDateTime) = 1
)
SELECT
*
FROM cte
ORDER BY ApptDateTime
......这很好用;我得到了一份记录清单,按日期排序。但是,如果我只想查看今天之前的日期并引入WHERE
:
;WITH cte
AS
(SELECT
urn,
CONVERT(DATETIME, ApptDateTime) AS ApptDateTime
FROM data
WHERE ISDATE(ApptDateTime) = 1
)
SELECT
*
FROM cte
WHERE ApptDateTime < GETDATE()
ORDER BY ApptDateTime
我收到错误
从字符串转换日期和/或时间时转换失败。
我无法在表格中看到任何狡猾的非日期,非NULL值,即使我有任何不可能CONVERT
的内容编辑导致问题成为CTE中SELECT
的一部分。但是,当我试图比较日期时间时,它只会抛出该错误。这看起来很简单,我确定我错过了一些令人眼花缭乱的东西 - 但我无法看到它。
编辑:如果我将结果发送到临时表,然后对其进行比较......它运行正常!
SELECT
urn,
convert(datetime,ApptDateTime) as ApptDateTime
into #temp FROM data
WHERE ISDATE(ApptDateTime) = 1
SELECT
*
FROM #temp
WHERE ApptDateTime < getdate()
ORDER BY ApptDateTime
DROP TABLE #temp
答案 0 :(得分:1)
尝试添加以下条件:WHERE (CASE WHEN ISDATE(ApptDateTime) = 1 THEN ApptDateTime ELSE NULL END) < GETDATE()
我在几天之前遇到了同样的问题,并通过添加CASE
来解决。
不清楚SQL如何执行条件。
我还需要找到相同的实际原因。如果我找到任何内容,我会在同一个帖子中发帖。
编辑:如果您在实际查询的执行计划中看到,它将显示ApptDateTime&lt;在ISDATE(ApptDateTime)= 1之前的GETDATE()导致错误。
原因是WHERE子句不遵循短路规则。参考:Is the SQL WHERE clause short-circuit evaluated?