2013-06-04 104 views
1

年前,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') 

現在假設我有60條記錄產生select。我只需要根據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

你的意思是時間是正確的,而日期不是? – Aeronth

回答

0

我相信你的左側只想更新DateTimeField1 & 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'); 
+1

謝謝Parag,完美的作品:) – Mario

+0

最受歡迎@Mario。我很高興解決方案幫助:) –

1

如果一個字段始終爲1900-01-01,但時間正確,另一個字段爲12:00:00 AM但日期正確,則可以將它們添加在一起。

UPDATE Test 
SET 
    DateTimeField1 = DateTimeField1 + DateTimeField3, 
    DateTimeField2 = DateTimeField2 + DateTimeField3 
WHERE (DateTimeField1 < '20000101') OR (DateTimeField2 < '20000101') 

請參閱this SQL Fiddle

1900-01-01是「零」日期,因此如果將其添加到其他內容中,則會得到相同的值。 12:00:00 AM是「零」時間。

如果有些情況下DateTimeField1具有正確的日期但DateTimeField2沒有,您可能希望將其作爲兩個單獨的查詢來執行此操作。

+0

將這兩個字段加在一起是一個好主意,但是你的where子句可能導致一些不應該發生的更新。對每個字段使用單獨的查詢會更安全。 –

+0

@Joe如果只有一個字段不正確,此查詢將更新這兩個字段。它應該只更新不正確的字段。嘗試用'CASE'語句修改它。 –

+0

感謝您的解決方案喬。像其他人說,它不完全是我在找什麼,但它給了我一些好主意:) – Mario

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,其中右側是一個時間和左側是一個日期。此查詢正確的日期時間

+0

我相信@Mario也想更新DateTimeField1和DateTimeField2。此查詢只更新第一個字段。 –

+0

是的,我需要更新兩個,事實上總共有6個領域,我需要檢查。感謝您的建議。 – Mario

+0

@ParagMeshram,其實這個查詢不會更新任何東西。此查詢顯示瞭如何解決問題的方法。 –

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') 
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' 

這是通過檢查,看看日期和時間,轉換爲float,然後地板(刪除部分時間)等於1900年1月1日

由於DateTimeField1或DateTimeField2的日期部分基本上爲0,而DateTimeField3的時間部分爲0,因此可以簡單地將兩者相加。

0

這樣做,這將是最簡單的方法:我知道這會爲SQL Server 2005和2008年的工作,但我不知道2000年版,所以首先試試這項

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' 

解釋是這樣的:datetime存儲爲浮點值,其中int部分是日期,小數部分是時間。因此,通過​​您可以獲取日期部分,並且可以在將日期部分從中減去後,將其添加到DateTimeField1和DateTimeField2中。 對於1900-01-01日期部分將爲零:select cast(0 as datetime),但它仍然有效。