2012-06-18 7 views
5

Ich habe ein Paar Spalten, die leider falsch als TIMESTAMP(6) anstelle von TIMESTAMP(6) WITH TIME ZONE definiert wurden. Ich möchte diese Spalten vom alten, falschen Datentyp auf den neuen, korrekten umwandeln. Darüber hinaus scheinen die Werte in E (S | D) T erfasst worden zu sein und ich brauche den Wert in UTC.Wie aktualisiert man eine TIMESTAMP-Spalte zu TIMESTAMP MIT ZEITZONE in Oracle

Bisher war die beste, die ich habe ist:

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; 

Leider, das mich mit Datenblätter, die wie 15-JUN-12 05.46.29.600102000 PM -04:00 aussieht, wenn ich 15-JUN-12 09.46.29.600102000 PM UTC wollen (oder wie Oracle würde es formatieren).

Ich habe select dbtimezone from dual; getan und es zeigt mir +00:00, so bin ich mir nicht sicher, wie es weitergeht. Im Idealfall wäre ich in der Lage, dies in reiner DML zu tun, und habe DST auf der Grundlage der alten Datumswerte (die ich sicher in der Zeitzone Amerika/New_York bin).

Antwort

3

Mit einem little help from @JustinCave, kam ich auf die folgende Lösung, die genau das, was erreicht ich wollte:

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

Für mich sieht es gut aus.

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

gibt:

2012-06-15 09:46:20 

Sie einfach in Land mit 4 Stunden Differenz zu UTC leben.

auch versuchen, so etwas wie:

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

Ja, ich in einer Zeitzone leben, das ist zur Zeit ein 4-Stunden-Offset, aber ich habe Oracle auf UTC (oder zumindest ich probiert) konfiguriert, weshalb ich die Ausgabe von 'Select dbtimezone von Dual;'. Ich werde mit 'TO_CHAR' experimentieren, um zu sehen, ob ich damit das Format des in der neuen Spalte gespeicherten Wertes ändern kann. –