2012-06-18 24 views
5

Mam parę kolumn, które zostały niestety niepoprawnie zdefiniowane jako TIMESTAMP(6) zamiast TIMESTAMP(6) WITH TIME ZONE. Chciałbym przenieść te kolumny ze starego, niewłaściwego typu danych do nowego, poprawnego. Ponadto wydaje się, że wartości zostały przechwycone w E (S | D) T i potrzebuję wartości w UTC.Jak zaktualizować kolumnę TIMESTAMP do TIMESTAMP WITH TIME STONE w Oracle

Dotychczas najlepszy mam to:

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; 

Niestety, pozostawia mnie z danymi, które wygląda jak 15-JUN-12 05.46.29.600102000 PM -04:00, kiedy chcę 15-JUN-12 09.46.29.600102000 PM UTC (lub Oracle jednak byłoby go sformatować).

Zrobiłem select dbtimezone from dual; i pokazuje mi +00:00, więc nie jestem pewien, jak postępować. Najlepiej byłoby zrobić to w czystym DML i mieć konto DST w oparciu o stare wartości dat (które na pewno są w strefie czasowej America/New_York).

Odpowiedz

3

Z little help from @JustinCave, ja przybyłem na następujące rozwiązanie, które realizuje dokładnie to, co chciałem:

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

Dla mnie wygląda dobrze.

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

daje:

2012-06-15 09:46:20 

po prostu żyć w kraju o 4 godziny różnicy do czasu UTC.

spróbować też coś takiego:

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

Tak, ja mieszkam w strefie czasowej, która jest obecnie 4-godzinne przesunięcie, ale mam Oracle skonfigurowane domyślnie do UTC (lub przynajmniej próbowałem), dlatego wspomniałem o wyjściu 'select dbtimezone from dual;'. Będę eksperymentować z 'TO_CHAR', aby sprawdzić, czy mogę użyć tego do zmiany formatu wartości przechowywanej w nowej kolumnie. –