17

我有很多这样的日期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

但收到此消息:

消息 241,级别 16,状态 1,第 2 行
从字符串转换日期和/或时间时转换失败。

4

5 回答 5

20

发生错误是因为您(或设计此表的人)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在客户端上进行格式化,或CONVERT在 SQL 中使用。当您有一个有效的日期作为字符串文字时,您可以使用:

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

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

有一个流行的术语——垃圾进,垃圾出。如果您的数据类型选择(或设计表格的人的数据类型选择)固有地允许垃圾进入您的表格,那么您将永远无法转换为日期(更不用说转换为特定格式的字符串)。请修复它。或者问设计桌子的人(再次,非常好)来修复它。

于 2013-03-10T00:08:08.327 回答
15

采用SELECT CONVERT(date, '20140327')

在你的情况下,

SELECT [FIRST_NAME],
       [MIDDLE_NAME],
       [LAST_NAME],
       CONVERT(date, [GRADUATION_DATE])     
FROM mydb
于 2014-03-27T10:11:01.877 回答
8

在您的情况下,它应该是:

Select convert(datetime,convert(varchar(10),GRADUATION_DATE,120)) as
'GRADUATION_DATE' from mydb
于 2015-09-29T17:49:38.093 回答
0

我也遇到了同样的问题,我以 bigint 格式接收 Transaction_Date 为 YYYYMMDD。因此,我使用以下查询将其转换为日期时间格式,并以日期时间格式将其保存在新列中。我希望这对你也有帮助。

SELECT
convert( Datetime, STUFF(STUFF(Transaction_Date, 5, 0, '-'), 8, 0, '-'), 120) As [Transaction_Date_New]
FROM mydb
于 2020-09-23T08:45:39.433 回答
0

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

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

假设您没有 WHERE 子句,没关系,即使它不是像“00000000”这样的有效日期(在我的情况下),转换也会尝试返回所有日期。

但是,如果您需要 WHERE 子句,那么您可以看到如下消息: 在此处输入图像描述

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

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
于 2021-03-11T20:04:14.640 回答