我在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
从字符串转换日期和/或时间时转换失败。
答案 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;
现在您不必担心格式化 - 您始终可以在客户端上格式化为YYYYMMDD
或YYYY-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 子句,那么你可以看到这样的消息:
所以我测试了上面提到的一些方法的组合,例如:
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