【问题标题】:Invalid datetime Cast when WHERE added in SQL Server在 SQL Server 中添加 WHERE 时,日期时间转换无效
【发布时间】:2016-02-11 16:04:47
【问题描述】:

我有一列字符日期时间值,一些无效的日期,我可以选择没有错误:

SELECT CAST(cDatetime as datetime)
FROM table 
WHERE cDatetime like '[01][0-9]/[0-3][0-9]/%'

但是,如果我在上面添加 WHERE 子句,我会收到一个转换失败错误:

SELECT CAST(cDatetime as datetime)
FROM table 
WHERE cDatetime like '[01][0-9]/[0-3][0-9]/%'
      and CAST(cDatetime as datetime)>='2015-01-01'

或者这个:

SELECT tDatetime
FROM (SELECT CAST(cDatetime as datetime) tDatetime
       FROM table 
       WHERE cDatetime like '[01][0-9]/[0-3][0-9]/%') validdates
WHERE tDatetime>='2015-01-01'

估计的执行计划有一个索引查找,谓词为:

CAST(cDatetime as datetime)>'2015-01-01' 
AND cDatetime like '[01][0-9]/[0-3][0-9]/%'

这似乎可以解释错误。如何强制执行计划先处理子查询?我的备份计划是创建一个函数来处理日期转换,这将被排除在优化之外。有没有更好的办法?

【问题讨论】:

  • 没有办法先强制子查询,我知道。
  • @Frisbee 可以使用 cte 强制,但作为子查询,你是对的。
  • @SeanLange CTE 只是语法。

标签: sql-server tsql casting sql-execution-plan


【解决方案1】:

cDatetime 是字符串吗? 日期是字符串形式:'12/31/2015' ?

错误的代码,但是....它必须有效。

SELECT CAST(cDatetime as datetime)
FROM table 
WHERE cDatetime like '[01][0-9]/[0-3][0-9]/%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/1%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/200%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/2010%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/2011%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/2012%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/2013%'
      and cDatetime not like '[01][0-9]/[0-3][0-9]/2014%'

【讨论】:

    【解决方案2】:

    您可以在下面使用ISDATE

    SELECT CAST(cDatetime as datetime)
    FROM table 
    WHERE ISDATE(cDatetime) = 1
          and CAST(cDatetime as datetime) >= '2015-01-01'
    

    【讨论】:

    • 不保证 ISDATE 会首先发生。你不能在 where 子句中这样短路。
    • @SeanLange 在你的回答中,不能保证派生表会首先发生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多