2011-09-05 23 views
5

Estoy buscando la mejor manera de cambiar un tipo de datos de una columna en una tabla poblada. Oracle solo permite cambiar el tipo de datos en columnas con valores nulos.Alterar el tipo de datos de columna en la base de datos de producción

Mi solución, hasta ahora, es una declaración PLSQL que almacena los datos de la columna a ser modificados en una colección, altera la mesa y luego itera sobre la colección, la restauración de los datos originales con tipo de datos convertida.

-- Before: my_table (id NUMBER, my_value VARCHAR2(255)) 
-- After: my_table (id NUMBER, my_value NUMBER) 

DECLARE 
    TYPE record_type IS RECORD (id NUMBER, my_value VARCHAR2(255)); 
    TYPE nested_type IS TABLE OF record_type; 
    foo nested_type; 
BEGIN 
    SELECT id, my_value BULK COLLECT INTO foo FROM my_table; 
    UPDATE my_table SET my_value = NULL; 
    EXECUTE IMMEDIATE 'ALTER TABLE my_table MODIFY my_value NUMBER'; 
    FOR i IN foo.FIRST .. foo.LAST 
    LOOP 
    UPDATE my_table 
     SET = TO_NUMBER(foo(i).my_value) 
     WHERE my_table.id = foo(i).id; 
    END LOOP; 
END; 
/

Estoy buscando una forma más experimentada de hacerlo.

+2

La respuesta simple es dejar su base de datos en producción durante unas horas mientras lo hace correctamente. Nunca ** garantizarás ** que tienes todo lo correcto a menos que dejes de escribir a la base de datos. – Ben

+0

¿Qué tan grande es la mesa? ¿La tabla debe estar disponible para la aplicación durante este tiempo? –

Respuesta

6

La solución es incorrecta. La declaración alter table hace una confirmación implícita. Así que la solución tiene los siguientes problemas:

  • No se puede deshacer después de alterar la instrucción alter table y si se bloquea la base de datos después de la declaración de modificación de tabla se perderán los datos
  • Entre el selecto y los usuarios de actualización pueden hacer cambios a los datos

En su lugar, debería echarle un vistazo a la redefinición en línea de oracle.

+0

Gracias, steve. Resulta que tendré una ventana de tiempo para hacer el mantenimiento, así que usaré el enfoque de @Rene. –

5

Su solución parece un poco peligrosa para mí. Cargar los valores en una colección y posteriormente eliminarlos de la tabla significa que estos valores ahora solo están disponibles en la memoria. Si algo sale mal, se pierden.

El procedimiento correcto es:

  1. añadir una columna del tipo correcto de la tabla.
  2. Copie los valores a la nueva columna.
  3. Suelta la columna anterior.
  4. Cambie el nombre de la nueva columna al nombre de las columnas antiguas.
+0

¿Resuelve esto el problema de la pérdida de datos incluso si otro usuario realiza cambios en los datos, como señala @steve? –

+0

No, no es así. Pero te dejará con todos tus datos intactos en los casos en que puedas llevar la aplicación fuera de línea para su mantenimiento. – Rene

+0

Agradezco su pensamiento en esto, gracias. –

Cuestiones relacionadas