2012-06-18 59 views
5

我有一對不幸被錯誤地定義爲TIMESTAMP(6)而不是TIMESTAMP(6) WITH TIME ZONE的列。我想將這些列從舊的,錯誤的數據類型遷移到新的正確的列。最重要的是,這些值似乎是在E(S | D)T中捕獲的,我需要UTC中的值。如何在Oracle中將TIMESTAMP列更新爲TIMESTAMP WITH TIME ZONE

到目前爲止,我已經得到了最好的是:

alter table OOPSIE_TABLE add (
    NEW_COLUMN_A timestamp(6) with time zone, 
    NEW_COLUMN_B timestamp(6) with time zone 
); 
update OOPSIE_TABLE set 
    NEW_COLUMN_A = COLUMN_A, 
    NEW_COLUMN_B = COLUMN_B 
; 
alter table OOPSIE_TABLE drop column (
    COLUMN_A, 
    COLUMN_B 
); 
alter table OOPSIE_TABLE rename column NEW_COLUMN_A to COLUMN_A; 
alter table OOPSIE_TABLE rename column NEW_COLUMN_B to COLUMN_B; 

不幸的是,給我留下了,看起來像15-JUN-12 05.46.29.600102000 PM -04:00,當我想15-JUN-12 09.46.29.600102000 PM UTC(或不過甲骨文將其格式化)數據。

我做了select dbtimezone from dual;,它顯示我+00:00,所以我不知道如何繼續。理想情況下,我可以在純DML中執行此操作,並根據舊日期值(我確信它們位於America/New_York時區)對其進行DST計算。

回答

3

隨着little help from @JustinCave,我得出了以下的解決方案,實現正是我想要的:

-- Rename the old columns so we can use them as a data source *AND* so 
-- we can roll back to them if necessary. 
alter table OOPSIE_TABLE rename column COLUMN_A to OLD_COLUMN_A; 
alter table OOPSIE_TABLE rename column COLUMN_B to OLD_COLUMN_B; 
-- Define COLUMN_A and COLUMN_B to have TIME ZONE support. 
alter table OOPSIE_TABLE add (
    COLUMN_A timestamp(6) with time zone, 
    COLUMN_B timestamp(6) with time zone 
); 
-- Populate the "new" columns with the adjusted version of the old data. 
update OOPSIE_TABLE set 
    COLUMN_A = from_tz(OLD_COLUMN_A, 'America/New_York') at time zone 'UTC', 
    COLUMN_B = from_tz(OLD_COLUMN_B, 'America/New_York') at time zone 'UTC' 
; 
2

對我來說它看起來不錯。

`SELECT SYS_EXTRACT_UTC(TIMESTAMP '2012-06-15 05:46:20 -04:00') FROM DUAL;` 

給出:

2012-06-15 09:46:20 

你只住在全國有4個小時的時差爲UTC。

也可以嘗試這樣的:

SELECT to_char(new_column_a, 'YYYY-MM-DD HH24:MI:SS TZD'), sys_extract_utc(new_column_a) FROM oopsie_table; 
+0

是的,我生活在一個時區是目前是4小時的偏移量,但我將Oracle配置爲默認爲UTC(或者至少我嘗試了),這就是爲什麼我提到'select dbtimezone from dual;'的輸出。我將嘗試使用'TO_CHAR'來查看是否可以使用它來更改存儲在新列中值的格式。 –

相關問題