将YYYYMMDD转换为DATE

时间:2013-03-09 23:56:23

标签: sql sql-server sql-server-2008-r2

我在varchar中有很多日期,如下所示:

20080107
20090101
20100405
...

如何将它们转换为这样的日期格式:

2008-01-07
2009-01-01
2010-04-05

我尝试过使用它:

SELECT [FIRST_NAME]
      ,[MIDDLE_NAME]
      ,[LAST_NAME]      
      ,cast([GRADUATION_DATE] as date)      
  FROM mydb

但是得到这个消息:

  

Msg 241,Level 16,State 1,Line 2
从字符串转换日期和/或时间时转换失败。

5 个答案:

答案 0 :(得分:19)

错误发生的原因是您(或设计此表的任何人)have a bunch of dates in VARCHAR。你为什么(或设计这个表的人)将日期存储为字符串?您(或设计此表的人)是否也将薪水,价格和距离存储为字符串?

要查找导致问题的值(因此您(或设计此表的任何人)可以修复它们):

SELECT GRADUATION_DATE FROM mydb
  WHERE ISDATE(GRADUATION_DATE) = 0;

打赌你至少有一排。修复这些值,然后修复表。或者询问设计表格的人是否修复了表格。非常好。

ALTER TABLE mydb ALTER COLUMN GRADUATION_DATE DATE;

现在您不必担心格式化 - 您始终可以在客户端上格式化为YYYYMMDDYYYY-MM-DD,或在SQL中使用CONVERT。如果有效日期为字符串文字,则可以使用:

SELECT CONVERT(CHAR(10), '20120101', 120);

...但最好在客户端完成(如果有的话)。

有一个流行的术语 - 垃圾输入,垃圾输出。如果您的数据类型选择(或者设计表格的任何人的数据类型选择)本身就是您永远无法转换为日期(更不用说转换为特定格式的字符串)允许垃圾进入你的桌子。请修理它。或者询问设计表格的人(再次,非常好)来修复它。

答案 1 :(得分:9)

使用SELECT CONVERT(date, '20140327')

在你的情况下,

SELECT [FIRST_NAME],
       [MIDDLE_NAME],
       [LAST_NAME],
       CONVERT(date, [GRADUATION_DATE])     
FROM mydb

答案 2 :(得分:0)

在你的情况下应该是:

Select convert(datetime,convert(varchar(10),GRADUATION_DATE,120)) as
'GRADUATION_DATE' from mydb

答案 3 :(得分:0)

我还遇到了同样的问题,即我以bigint格式接收YYYYMMDD的Transaction_Date。所以我使用下面的查询将其转换为Datetime格式,并将其保存在datetime格式的新列中。希望对您有帮助。

SELECT
convert( Datetime, STUFF(STUFF(Transaction_Date, 5, 0, '-'), 8, 0, '-'), 120) As [Transaction_Date_New]
FROM mydb

答案 4 :(得分:0)

只是添加有关上述所有解决方案的更多信息:

SELECT [FIRST_NAME],
       [MIDDLE_NAME],
       [LAST_NAME],
       CONVERT(date, [GRADUATION_DATE])     
FROM mydb

假设您没有 WHERE 子句,没关系,即使它不是像“00000000”这样的有效日期(就我而言),Convert 也会尝试返回所有日期。

但是,如果你需要一个 WHERE 子句,那么你可以看到这样的消息: enter image description here

所以我测试了上面提到的一些方法的组合,例如:

DECLARE @DateStart datetime = '2021-02-18'
DECLARE @DateEnd datetime = '2021-02-19'
SELECT [FIRST_NAME],
       [MIDDLE_NAME],
       [LAST_NAME],
       CONVERT(date, [GRADUATION_DATE]) 
FROM mydb
WHERE 
--THIS LINE SHOULD BE ENOUGTH TO AVOID WRONG DATES, BUT IT IS NOT
ISDATE([GRADUATION_DATE]) = 1 AND
CONVERT(char(10), [GRADUATION_DATE], 120) BETWEEN @DateStart and @DateEnd

最后我成功地使用了这种方式:

DECLARE @DateStart datetime = '2021-02-18'
DECLARE @DateEnd datetime = '2021-02-19'
SELECT [FIRST_NAME],
       [MIDDLE_NAME],
       [LAST_NAME],
       CONVERT(date, [GRADUATION_DATE]) 
FROM mydb
WHERE 
CONVERT(char(10), 
-- I ADDED THIS LINE TO IGNORE WRONG DATES
CASE WHEN ISDATE([GRADUATION_DATE]) = 1 THEN [GRADUATION_DATE] ELSE '1900-01-01' END, 120) 
BETWEEN @DateStart and @DateEnd