将varchar转换为SQL Server 2008中格式错误的值的日期

时间:2014-08-06 13:35:44

标签: sql-server sql-server-2008

这整个日期代码超出了我的理解范围,但我需要将查询结果中的列从varchar转换为date。我有一些格式错误,我试图将它们过滤掉。

SET DATEFORMAT dmy
SET LANGUAGE us_english

select convert(datetime, some_date, 103) 
from   some_table 
where  isdate(some_date) = 1

我一直在

  

从字符串

转换日期和/或时间时转换失败

查询格式不正确的值时,我会得到这两条记录

some_date 
---------
621
232

有没有办法使用isdate验证格式?

谢谢,令人沮丧的Oracle DBA。

修改

尝试了@Sean Lange的建议,确实看起来很有希望

select convert(datetime, some_date, 103)
from ( select * from some_table where isdate(some_date) = 1 ) 

但后来我添加了一个where子句

select convert(datetime, some_date, 103)
from ( select * from some_table where isdate(some_date) = 1 ) 
where convert(datetime, some_date ,103) between 
       convert(datetime, '01/07/2014') 
       and convert(datetime,'31/07/2014')

如何在from?

之前执行where子句

3 个答案:

答案 0 :(得分:1)

既然我们知道有效日期看起来像dd / mm / yyyy那么简单的结构测试呢?

select convert(datetime, some_date, 103) 
from some_table
where len(some_date) = 10 --must have exactly the expected number of characters

这可以扩展(取决于要求)

  and some_date like '__/__/____'

或者

  and some_date like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]'

任何更好的东西都可能需要你把一个自定义函数放在一起,在try块中执行CONVERT,如果它是一个无效的记录,则在catch块中返回NULL。取决于您的要求......

答案 1 :(得分:0)

问题正在发生并将继续发生,因为您无法确定sql引擎将在此处采用的顺序。有一次它可能首先过滤行,而另一次它会进行转换。所以你需要做的是强制引擎的工作顺序。我们可以通过使用CTE来获取我们想要转换的行。

with MyCTE as
(
    select some_date
    from some_table
    where ISDATE(some_date) = 1
)

select CONVERT(datetime, some_date, 103)
from MyCTE

答案 2 :(得分:0)

如果你肯定这些是唯一的格式不正确的值,并且所有格式不正确的值都是这样的话,你可以继续使用hackish CASE语句

SELECT (CASE WHEN LEN(datetime) > 3 THEN convert(datetime, some_date, 103) ELSE NULL),
...

它真的不优雅,但是因为有太多碎片格式,所以日期很难变得优雅。如果可能的话,它可以节省更多的麻烦,只是为了确保您的数据首先通过表单验证和正则表达式的东西正确格式化,但由于这并不总是可行,我们有这样糟糕的黑客来修补自己。祝你好运!