我有一个数据类型= varchar(50)的字段,我有几个不同的日期格式,如下所示:
2019-06-17
01/11/19
2019-08-21
08/04/13
10/03/17
11/22/08
2018-06-07
我在表格中添加了一个新字段,数据类型=日期。如何将varchar(50)字段中的所有日期转换为日期字段中的实际日期?
我认为这很简单:
update TBL_MULTI_LD_Balance_HIST
set [actual_date] = CONVERT(VARCHAR(10), Date, 110)
update TBL_MULTI_LD_Balance_HIST
set [actual_date] = CAST([Date] as Date)
但现在我收到了这个错误:' Msg 241,Level 16,State 1,Line 65 从字符串转换日期和/或时间时转换失败。'
答案 0 :(得分:2)
你可以运行
SELECT *
FROM TBL_MULTI_LD_Balance_HIST
WHERE ISDATE([date]) = 0
这将为您提供给您提供问题的列表。然后,您可以手动修复这些并在之后运行原始更新。这不是全面的,但至少会给你一个很好的起点。
答案 1 :(得分:1)
在SQL Server 2012+中,它与您建议的一样简单,因为SQL Server在转换为日期时非常灵活。但有些事情无法转换。而不是cast()
使用try_cast()
或try_convert()
:
update TBL_MULTI_LD_Balance_HIST
set [actual_date] = try_cast([Date] as Date);
在执行此操作之前,您可以通过执行以下操作获取未转换的值:
select [date]
from TBL_MULTI_LD_Balance_HIST
where try_cast([Date] as date) is null;
如果所有值都符合您的格式,那么您就不会有问题。 cast()
只会起作用。事实并非如此,因此2012年之前没有好的解决方案。你可以尝试:
update TBL_MULTI_LD_Balance_HIST
set [actual_date] = (case when [date] like '[0-1][0-9]/[0-3][0-9]/[0-9][0-9]'
then cast([Date] as Date)
when [date] like '[12][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]'
then cast([Date] as Date)
end);
显然,这仍然可以得到不好的比赛,例如4月34日,但在这种情况下通常不会出现问题。人们把一些字符串写成“无”。
答案 2 :(得分:1)
一种选择是使用简单的CASE。 但是,您的日期不明确,例如01/11/19
...假设MDY
这将转换为2019-01-11
示例强>
Declare @YourTable Table ([SomeCol] varchar(50),Date date )
Insert Into @YourTable Values
('2019-06-17',null)
,('01/11/19',null)
,('2019-08-21',null)
,('08/04/13',null)
,('10/03/17',null)
,('11/22/08',null)
,('2018-06-07',null)
,('Not a Date',null)
,('2017-31-31',null)
Update @YourTable
set [Date] = case when IsDate(SomeCol)=0 then null else convert(date,SomeCol) end
Select * from @YourTable
更新了表格
SomeCol Date
2019-06-17 2019-06-17
01/11/19 2019-01-11
2019-08-21 2019-08-21
08/04/13 2013-08-04
10/03/17 2017-10-03
11/22/08 2008-11-22
2018-06-07 2018-06-07
Not a Date NULL
2017-31-31 NULL
答案 3 :(得分:0)
您可以尝试替换所有日期,并为所有日期采用相同的格式,然后转换。