在SQL Server中有一个表,其中包含一个带有日期数据的varchar
列。不幸的是,日期是一系列不同的格式。
2012-05-01
27/05/2012
07MAY2014
19/07/13
可能还有其他人,但到目前为止我所遇到过的一切。
我需要将这些列入datetime
列到另一个表中,因此我一直在尝试将它们选为标准日期时间值。起初,我认为这很容易:
UPDATE myTable
SET myDateColumn = CONVERT(DATETIME, myDateColumn, 103)
WHERE ISDATE(myDateColumn) = 0
但问题是SQL Server将dd/mm/yy
和dd/mm/yyyy
视为单独的格式。前者是代码3,后者是代码103.因此,无论以何种方式运行更新,它都会以相反的格式窒息。
我是否可以根据日期格式选择/更新,并将所有这些日期转换为单一有效的DateTime
格式?
答案 0 :(得分:3)
我的猜测是你只需要尝试区分不同的类并以适当的方式处理每个案例。像这样:
declare @tab table (d varchar(20))
insert @tab values ('2012-05-01'),('27/05/2012'),('07MAY2014'),('19/07/13')
select
case
when isnumeric(left(d,4)) = 1 then cast(d as date)
when len(d) = 10 then convert(date, d, 103)
when len(d) = 8 then convert(date, d, 3)
when charindex('/',d) = 0 and isnumeric(d) = 0 then convert(date, d, 106)
end as [date]
from @tab
输出:
date
----------
2012-05-01
2012-05-27
2014-05-07
2013-07-19
它可能效率不高,但我认为这是一次性操作。我没有把它写成更新语句,但查询应该很容易适应,如果可能的话,你应该考虑将转换后的日期添加为新的正确日期时间列。
编辑:这是相应的更新声明:
update @tab
set d =
case
when isnumeric(left(d,4)) = 1 then cast(d as date)
when len(d) = 10 then convert(date, d, 103)
when len(d) = 8 then convert(date, d, 3)
when charindex('/',d) = 0 and isnumeric(d) = 0 then convert(date, d, 106)
end
from @tab
答案 1 :(得分:1)
在SQL Server 2012中,您可以使用try_convert()
。否则,您可以进行多次更新:
UPDATE myTable
SET myDateColumn = CONVERT(DATETIME, myDateColumn, 103)
WHERE ISDATE(myDateColumn) = 0 AND MyDateColumn like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]';
UPDATE myTable
SET myDateColumn = CONVERT(DATETIME, myDateColumn, 3)
WHERE ISDATE(myDateColumn) = 0 AND MyDateColumn like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9]';
注意:where
子句可能适用于update
。它不适用于select
。您可能还需要使用case
:
UPDATE myTable
SET myDateColumn = (CASE WHEN ISDATE(myDateColumn) = 0 AND MyDateColumn like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]'
THEN CONVERT(DATETIME, myDateColumn, 103)
ELSE myDateColumn
END)
WHERE ISDATE(myDateColumn) = 0 AND MyDateColumn like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-0]'
此外,您将值重新放在同一列中,以便覆盖原始数据 - 并且您有另一个隐式转换回字符串我强烈建议您使用{{{}向表中添加另一列1}}数据类型并将正确输入的值放在那里。
答案 2 :(得分:1)
这非常可怕,但它适用于您的示例:
DECLARE @DodgyDates TABLE (
DateString VARCHAR(50));
INSERT INTO @DodgyDates VALUES ('2012-05-01');
INSERT INTO @DodgyDates VALUES ('27/05/2012');
INSERT INTO @DodgyDates VALUES ('07MAY2014');
INSERT INTO @DodgyDates VALUES ('19/07/13');
SELECT * FROM @DodgyDates;
--SELECT CONVERT(DATE, DateString) FROM @DodgyDates;--Fails
WITH DateDeconstruct AS (
SELECT
*,
CASE
WHEN DateString LIKE '____-__-__' THEN DateString
WHEN DateString LIKE '__/__/____' THEN RIGHT(DateString, 4) + '-' + SUBSTRING(DateString, 4, 2) + '-' + LEFT(DateString, 2)
WHEN DateString LIKE '__/__/__' THEN '20' + RIGHT(DateString, 2) + '-' + SUBSTRING(DateString, 4, 2) + '-' + LEFT(DateString, 2)
WHEN DateString LIKE '_________' THEN RIGHT(DateString, 4) + '-' + CONVERT(VARCHAR(2), DATEPART(MM, DateString)) + '-' + LEFT(DateString, 2)
END AS FixedString
FROM
@DodgyDates)
SELECT
DateString AS OriginalDate,
FixedString AS FixedDate,
CONVERT(DATE, FixedString) AS ConvertedDate
FROM
DateDeconstruct;
结果是:
OriginalDate FixedDate ConvertedDate
2012-05-01 2012-05-01 2012-05-01
27/05/2012 2012-05-27 2012-05-27
07MAY2014 2014-5-07 2014-05-07
19/07/13 2013-07-19 2013-07-19
答案 3 :(得分:0)
首先,您可以将所有数据转换为另一种格式,例如110
USA date fromat
,然后再次使用所需格式更新整个表格。