使用Isdate

时间:2015-09-18 14:48:27

标签: sql sql-server tsql

您好我在使用isdate进行验证时将字符串转换为日期存在问题,这是我的脚本

USE SomeDB
    SELECT  InstallDate
    FROM         tblInstalls
    WHERE     (ISDATE(InstallDate) = 0) AND (InstallDate IS NOT NULL)

- 结果---
27/05/2002
27/08/2004
19/06/2002
26/06/2002
17/05/2002
15/09/2002
15/04/2004
19/04/2004
22/04/2004
22/04/2004
22/06/904

现在我想转换哪个可以转换为103格式并忽略无法转换的数据......

USE SomeDB
SELECT  top 100   convert(DATETIME, InstallDate,  103))
FROM         tblInstalls
WHERE     (ISDATE(InstallDate) = 0) AND (InstallDate IS NOT NULL)


--- Result--
2002-05-27 00:00:00.000
2004-08-27 00:00:00.000
2002-06-19 00:00:00.000
2002-06-26 00:00:00.000
2002-05-17 00:00:00.000
2002-09-15 00:00:00.000
2004-04-15 00:00:00.000
2004-04-19 00:00:00.000
2004-04-22 00:00:00.000
2004-04-22 00:00:00.000
22/06/904< - 将nvarchar数据类型转换为日期时间数据类型导致超出范围的值

我的目标是以正确的日期格式清理数据并删除无法转换的不必要数据。希望并感谢你提前帮助..

2 个答案:

答案 0 :(得分:3)

首先,IsDate如果获得的字符串值是有效日期,则返回0
您需要按IsDate(InstallDate) = 1进行过滤 其次,由于服务器的默认日期格式不是0,因此IsDate可能会得到dmy

以下是可行的:

set dateformat dmy; -- NOTE THIS ROW!

select convert(datetime, InstallDate,  103)
from tblInstalls
where isdate(InstallDate) = 1 -- NOTE: IsDate returns 1 for valid dates 

see sql fiddle here.

顺便说一句,肖恩在他的回答中有一些非常好的观点,他只是错误的原因。 AFAIK,select子句将始终在where子句之后执行。

答案 1 :(得分:1)

这是因为您无法确定引擎将处理的顺序。它可以在过滤它们之前或之后进行行的转换。

作为旁注,你有顶级但没有订单。这将返回sql引擎想要的任何行,并且它不会始终保持一致。其次,InstallDate IS NOT NULL的谓词只是浪费了精力,因为你只是在过滤ISDATE = 1且NULL不是有效日期的行。

with ValidDates as
(
    select top 100 InstallDate
    from tblInstalls
    where ISDATE(InstallDate) = 1
    --need an order by here
)

select convert(DATETIME, InstallDate,  103)
from ValidDates