2012-06-18 49 views
5

Tengo un par de columnas que desafortunadamente se definieron incorrectamente como TIMESTAMP(6) en lugar de TIMESTAMP(6) WITH TIME ZONE. Me gustaría migrar esas columnas del tipo de datos viejo e incorrecto al nuevo y correcto. Además de eso, los valores parecen haber sido capturados en E (S | D) T y necesito el valor en UTC.Cómo actualizar una columna TIMESTAMP a TIMESTAMP WITH TIME ZONE en Oracle

Hasta el momento, la mejor que tengo es:

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; 

Por desgracia, eso me deja con los datos que se parece a 15-JUN-12 05.46.29.600102000 PM -04:00, 15-JUN-12 09.46.29.600102000 PM UTC cuando quiero (Oracle o como iba a formatearlo).

He hecho select dbtimezone from dual; y me muestra +00:00, así que no estoy seguro de cómo proceder. Idealmente, podría hacer esto en DML puro, y hacer que la cuenta para DST se base en los valores de fecha anteriores (que estoy seguro están en la zona horaria América/Nueva_York).

Respuesta

3

Con un little help from @JustinCave, llegué a la siguiente solución, que lleva a cabo exactamente lo que quería:

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

Para mí se ve bien.

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

da:

2012-06-15 09:46:20 

Simplemente viven en el país con diferencia 4 hora UTC.

Prueba también algo así como:

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

Sí, yo vivo en una zona horaria que es actualmente un desplazamiento de 4 horas, pero tengo Oracle configurado para usar UTC por defecto (o al menos lo intenté), por lo que mencioné la salida de 'select dbtimezone from dual;'. Voy a experimentar con 'TO_CHAR' para ver si puedo usar eso para cambiar el formato del valor almacenado en la nueva columna. –

Cuestiones relacionadas