为什么在比较数据时case语句失败?

时间:2018-10-15 05:58:32

标签: sql sql-server tsql

我已将 OpeningDate 存储为varchar(100),并将 OpeningTime 存储为表中的时间。

我已经尝试了一切,但这会引发错误:

从字符串转换日期和/或时间时转换失败。

SELECT CONVERT(VARCHAR(100),CAST(OpeningDate AS DATE),106), --Cast to DATE first to get the style needed
       CASE WHEN 
            (   CAST(OpeningDate AS DATETIME)+ -- Cast to DATETIME
                CAST(OpeningTime AS DATETIME)  -- Also here
            ) < GETDATE() 
             THEN 1 
             ELSE 0 END AS OpeningVaild
FROM Works;

2 个答案:

答案 0 :(得分:2)

现在,一个答案已被删除-并附上我的评论...

有几个问题:

  • CONVERT样式106的意思是dd mon yyyy。这是您需要的输出格式吗?
  • 如果将2018-04-02之类的值强制转换为DATETIME,则这取决于文化。
  • 将日期值存储在字符串型列中是个坏主意。这将减慢您的查询速度,而且是错误的...

尝试一下:

SET LANGUAGE ENGLISH;
SELECT CAST('2018-04-02' AS DATETIME)

SET LANGUAGE GERMAN;
SELECT CAST('2018-04-02' AS DATETIME)

是4月2日还是2月4日?

现在尝试对DATE ...

进行强制转换

这有点古怪和怪异,但这是旧的...使用新格式DATETIMEDATETIME2可以避免这种情况。

另一种确定的方法是ISO8601格式。这是yyyy-MM-ddTHH:mm:ss。您可以在任何区域性中将类似2018-04-02T12:32:45的字符串转换为DATETIME

当然还有可能出现无效字符串,例如2017-02-29(2017年2月29日!)或字符串列中的任何废话数据...

您可以使用ISDATE(请参阅RegBes的答案)or you might try TRY_CAST() (needs v2012+)搜索废品数据。

另一个选择是使用XML方法(自v2005起)模拟TRY_CAST

DECLARE @SomeDates TABLE(d VARCHAR(100));
INSERT INTO @SomeDates VALUES('2018-04-02'),('2017-02-29'),('crap data')

SELECT TRY_CAST(d AS DATE)      --needs v2012 
      ,TRY_CONVERT(DATE,d,102)  --needs v2012 and allows to specify the mask (102: yyyy.mm.dd)
      ,(SELECT d FOR XML PATH('x'),TYPE)
       .value('(/x/d/text())[1] cast as xs:date?','datetime')
FROM @SomeDates;

答案 1 :(得分:1)

我怀疑您的OpeningDate字段中的某些数据可能不是有效的日期格式。

运行此命令以获取所有可能有问题的记录

select *
from works
where isdate(OpeningDate) = 0