以特定格式将文本转换为Datetime

时间:2012-03-28 13:23:13

标签: sql-server sql-server-2008 tsql datetime type-conversion

我需要一个表达式,只有在匹配VARCHARDATETIME,{{1}时才会将文本(dd/MM/yyyy)列转换为d/MM/yyyy }或dd/M/yyyy。如果它不匹配,那么我想要一个d/M/yyyy

我有这个......

NULL

然而,例如CASE ISDATE([DateField]) WHEN 1 THEN CONVERT(DATETIME,[DateField],103) ELSE NULL END 失败了 - 使用“从字符串转换日期时转换失败”错误 - 而我希望它返回'15/04/76'

示例输出

NULL

有没有办法迫使'1/6/1976' -> 1976-06-01 '01/06/1976' -> 1976-06-01 '13/06/2001' -> 2001-06-13 '06/13/2001' -> NULL '13/06/76' -> NULL 验证给定的格式?

The documentation似乎暗示......

  

ISDATE仅在与CONVERT函数一起使用时才是确定性的   指定了CONVERT样式参数,样式不等于0,100,   9,或109。

但是ISDATE只接受一个参数,那么如果我不这样做,我如何“将它与CONVERT函数一起使用”?

3 个答案:

答案 0 :(得分:1)

你可以在这里做一个嵌套的case语句。第一个可以检查你是否有一个10个字符串2 for day,2个月,4个for year和2个分隔符= 10个字符。

SET DATEFORMAT DMY;

    Case When DateField Like '%/%/[0-9][0-9][0-9][0-9]' 
         Then Case When IsDate(DateField) = 1 
                   Then CONVERT(DATETIME,[DateField],103) 
                   End
         End

修订:我更改了代码以使用类似搜索,强制在字符串末尾有一个/ YYYY,然后执行IsDate检查以允许一天和/或一个月。

答案 1 :(得分:1)

嗯,首先,为什么你要将日期时间值存储在varchar列中呢?由于各种原因,这是一个重要的罪,其中最重要的是,您无法验证数据是否(或可转换为)日期时间。您还应该考虑验证输入,即使您将列保留为varchar,因此您没有想要认为有效的各种各样的潜在格式。

所以这是一种方式,借用@G Mastros:

DECLARE @f TABLE(i INT, d VARCHAR(32));

INSERT @f VALUES
(1,'15/04/76'),
(2,'15/04/1976'),
(3,'1/3/1976'),
(4,'1/3/76'),
(5,'15/3/1976'),
(6,'22/22/22'),
(7,'Yesterday');

SET DATEFORMAT DMY;

SELECT i, d, d2 = CASE WHEN ISDATE(d) = 1
    AND d LIKE '%/[0-9][0-9][0-9][0-9]'
    THEN CONVERT(DATETIME, d, 103) END
  FROM @f;

结果:

i  d           d2
-  ----------  -----------------------
1  15/04/76    NULL
2  15/04/1976  1976-04-15 00:00:00.000
3  1/3/1976    1976-03-01 00:00:00.000
4  1/3/76      NULL
5  15/3/1976   1976-03-15 00:00:00.000
6  22/22/22    NULL
7  Yesterday   NULL

PS这将是SQL Server 2012中TRY_CONVERT的一个很好的例子。它正是你所要求的 - 它试图转换为指定的数据类型;如果不能,则返回NULL

答案 2 :(得分:0)

感谢回复人员。

我这样做了......

CASE ISDATE([DateField]) WHEN 1 THEN 
    CASE WHEN SUBSTRING([DateField],LEN([DateField])-4,1) = '/' THEN
        CASE WHEN CHARINDEX('/',[DateField],LEN([DateField])-3)=0 THEN
            CONVERT(datetime, [DateField] , 103) 
        END
    END
END

这是非常讨厌的事情,所以仍然会喜欢更整洁的东西!

但这也不起作用 - 它仍然是mm / dd / yyyy格式日期的错误!

废弃最后一条评论 - 它现在似乎有效吗?可能与SET DATEFORMAT

有关