TSQL日期转换失败 - 我无法理解结果集

时间:2011-01-25 01:31:14

标签: sql-server tsql sql-server-2008

我有一个临时区域,我正在尝试验证数据,经过多次验证迭代。目前,我正在使用nvarchar(50)列来解决一些问题,我试图将其转换为日期。

我知道字符串格式不正确导致日期转换失败的常见缺陷,所以这就是我正在做的事情。

SELECT *
  FROM ( SELECT * FROM STAGE_TABLE WHERE ISDATE(DATE_COL) = 1)
 WHERE CAST(DATE_COL AS DATE) < GETDATE()

...这导致标准“从字符串转换日期和/或时间时转换失败。”

但是这里的事情对我来说很奇怪。如果我将上述声明更改为以下内容:

SELECT CAST(DATE_COL AS DATE)
  FROM ( SELECT * FROM STAGE_TABLE WHERE ISDATE(DATE_COL) = 1)

...一切都很好,我所做的就是将演员从where子句移动到select子句。我想我在基本层面上缺少一些东西。

FWIW,如果我在没有STAGE_TABLE条款的情况下从WHERE ISDATE提取所有记录,我的日期字符串就会很差。

任何见解都非常感谢!

1 个答案:

答案 0 :(得分:3)

您应该发现第一个查询将两个WHERE子句合并为一个,并在ISDATE(失败)之前计算出CAST。

第二个查询显然必须首先处理WHERE,因此CAST永远不会看到错误的数据

我刚刚测试过并且可以验证:

create table STAGE_TABLE ( date_col nvarchar(50) )
insert into STAGE_TABLE select 'a'
insert into STAGE_TABLE select '20100101'

第一次查询

SELECT *
  FROM ( SELECT * FROM STAGE_TABLE WHERE ISDATE(DATE_COL) = 1) X
 WHERE CAST(DATE_COL AS DATE) < GETDATE()

第一个计划

  |--Filter(WHERE:(isdate([tempdb].[dbo].[STAGE_TABLE].[date_col])=(1)))
       |--Table Scan(OBJECT:([tempdb].[dbo].[STAGE_TABLE]), WHERE:(CONVERT(date,[tempdb].[dbo].[STAGE_TABLE].[date_col],0)<getdate()))

第二次查询

SELECT CAST(DATE_COL AS DATE)
  FROM ( SELECT * FROM STAGE_TABLE WHERE ISDATE(DATE_COL) = 1) X

第二个计划

  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(date,[tempdb].[dbo].[STAGE_TABLE].[date_col],0)))
       |--Filter(WHERE:(isdate([tempdb].[dbo].[STAGE_TABLE].[date_col])=(1)))
            |--Table Scan(OBJECT:([tempdb].[dbo].[STAGE_TABLE]))

似乎没有一个提示/选项来修复第一个查询(因为它被卷入一个WHERE子句),但你可以使用它来处理一个扫描过程中的两个条件。

SELECT *
  FROM (SELECT * FROM STAGE_TABLE) X
 WHERE CAST(CASE WHEN ISDATE(DATE_COL) = 1 THEN DATE_COL ELSE NULL END AS DATE) < GETDATE()