多年前,从MSSQL 6.5到MSSQL 2000的转换已经完成,他们本周才意识到转换无法转换某些日期时间列。现在我的任务是解决这个问题,我一直在试着如何保存一些我知道准确的信息。这是我需要解决的一个表的结构。
DateTimeField1 DateTimeField2 DateTimeField3
01/01/1900 5:50:00 PM 01/01/1900 5:52:00 PM 15/02/2005 12:00:00 AM
这是许多已损坏的记录中的一个示例,不幸的是我在转换之前无法访问任何备份。如您所见,日期部分是DateTime字段的默认值,是我需要修复的部分。我有以下选择,它给了我需要修复的行。
SELECT DateTimeField1, DateTimeField2, DateTimeField3
FROM Table1
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101')
现在假设我有来自select的60条记录。我需要仅基于DateTimeField3 DATE部分更新这些记录。上面的示例看起来像;
DateTimeField1 DateTimeField2 DateTimeField3
15/02/2005 5:50:00 PM 15/02/2005 5:52:00 PM 15/02/2005 12:00:00 AM
关于如何实现这一目标的任何想法?
答案 0 :(得分:1)
如果一个字段始终是1900-01-01,但是时间正确,而另一个字段是凌晨12:00:00但是日期正确,则可以将它们一起添加。
UPDATE Test
SET
DateTimeField1 = DateTimeField1 + DateTimeField3,
DateTimeField2 = DateTimeField2 + DateTimeField3
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101')
请参阅this SQL Fiddle。
1900-01-01是“零”日期,因此如果您将其添加到其他内容,则会得到相同的值。凌晨12:00:00是“零”时间。
如果有时DateTimeField1具有正确的日期但DateTimeField2没有,则您可能希望将其作为两个单独的查询执行。
答案 1 :(得分:0)
使用此查询:
SELECT DateTimeField1 =
convert(datetime,convert(int,convert(float,t.DateTimeField3))
+ convert(float,t.DateTimeField1)),
DateTimeField2 =
convert(datetime,convert(int,convert(float,t.DateTimeField3))
+ convert(float,t.DateTimeField2)),
FROM Table1 t
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101')
SQL Server
将datetime
存储为float
,其中右侧是时间,左侧是日期。此查询将正确日期时间左侧的错误日期时间的左侧替换为
答案 2 :(得分:0)
我相信您只想更新DateTimeField1
&amp; DateTimeField2
当它们小于'20000101'
时。 CASE
声明将负责不更新错误的字段。
尝试单个查询UPDATE
-
SQL SERVER 2008及以后 -
UPDATE Table1
SET DateTimeField1 = (CASE WHEN (DateTimeField1 < '20000101')
THEN CAST(CAST (DateTimeField3 AS DATE) AS DATETIME)
+ CAST (DateTimeField1 AS TIME)
ELSE DateTimeField1
END)
, DateTimeField2 = (CASE WHEN (DateTimeField2 < '20000101')
THEN CAST(CAST (DateTimeField3 AS DATE) AS DATETIME)
+ CAST (DateTimeField2 AS TIME)
ELSE DateTimeField2
END)
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101');
比SQL Server 2008更早 -
UPDATE Table1
SET DateTimeField1 = (CASE WHEN (DateTimeField1 < '20000101')
THEN DATEADD(DAY, 0, DATEDIFF(day, 0, DateTimeField3))
+ DATEADD(DAY, 0 - DATEDIFF(day, 0, DateTimeField1), DateTimeField1)
ELSE DateTimeField1
END)
, DateTimeField2 = (CASE WHEN (DateTimeField2 < '20000101')
THEN DATEADD(DAY, 0, DATEDIFF(day, 0, DateTimeField3))
+ DATEADD(DAY, 0 - DATEDIFF(day, 0, DateTimeField2), DateTimeField2)
ELSE DateTimeField2
END)
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101');
答案 3 :(得分:0)
尝试这样的东西,它应该适用于MSSQL 2000
UPDATE tab SET DateTimeField1 =
ltrim(str(datepart(year, DateTimeField3))) + '-' +
ltrim(str(datepart(month, DateTimeField3))) + '-' +
ltrim(str(datepart(day, DateTimeField3))) + ' ' +
ltrim(str(datepart(hour, DateTimeField1))) + ':' +
ltrim(str(datepart(minute, DateTimeField1))) + ':' +
ltrim(str(datepart(second, DateTimeField1))) + '.' +
ltrim(str(datepart(millisecond, DateTimeField1))) ,
DateTimeField2 = ltrim(str(datepart(year, DateTimeField3))) + '-' +
ltrim(str(datepart(month, DateTimeField3))) + '-' +
ltrim(str(datepart(day, DateTimeField3))) + ' ' +
ltrim(str(datepart(hour, DateTimeField2))) + ':' +
ltrim(str(datepart(minute, DateTimeField2))) + ':' +
ltrim(str(datepart(second, DateTimeField2))) + '.' +
ltrim(str(datepart(millisecond, DateTimeField2)))
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101')
答案 4 :(得分:0)
这应该做你需要的:
update <yourtable>
set
DateTimeField1 = case when cast('1 jan 1900' as datetime) = cast(floor(cast(DateTimeField1 as float)) as datetime) then DateTimeField1 + DateTimeField3 else date1 end,
DateTimeField2 = case when cast('1 jan 1900' as datetime) = cast(floor(cast(DateTimeField2 as float)) as datetime) then DateTimeField2 + DateTimeField3 else date2 end
where DateTimeField1 < '2 jan 1900' or DateTimeField2 < '2 jan 1900'
这可以通过检查日期和时间,转换为浮动然后淹没(删除时间部分)等于1900年1月1日。
由于DateTimeField1或DateTimeField2的日期部分基本上为0且DateTimeField3的时间部分为0,因此您只需将两者一起添加即可。
答案 5 :(得分:0)
最简单的方法是:
update Table1
set
DateTimeField1 = cast(cast(DateTimeField1 as float)-floor(cast(DateTimeField1 as float)) + floor(cast(DateTimeField3 as float)) as datetime
WHERE DateTimeField1 < '20000101'
update Table1
set
DateTimeField2 = cast(cast(DateTimeField2 as float)-floor(cast(DateTimeField2 as float)) + floor(cast(DateTimeField3 as float)) as datetime
WHERE DateTimeField2 < '20000101'
我知道它适用于SQL Server 2005和2008,但我不确定2000版,所以先测试一下。
解释如下:datetime
存储为浮点值,其中int部分是日期,小数部分是时间。因此,通过floor(cast(DateTimeField3 as float))
获取日期部分,您可以在从它们中减去日期部分之后将其添加到DateTimeField1和DateTimeField2。
对于1900-01-01,日期部分将为零:select cast(0 as datetime)
,但它仍然有效。