jueves, 18 de octubre de 2018

Como solucionar ORA-01439 modificando el tipo o precisión de una columna en una tabla con datos

Veamos la siguiente situación:

"Tienes una tabla en donde el tipo de dato definido para una columna específica, no corresponde con el modelaje que habías hecho. La tabla ya tiene tiempo en producción y la columna en cuestión, ya tiene datos.

Problema: Requieres cambiar el tipo de dato obligatoriamente, pero al ejecutar la modificación sobre la tabla, obtienes el siguiente error:"

SQL> ALTER TABLE CND_FACTURA MODIFY CODIGO_SEGURIDAD VARCHAR2(8 byte);

MODIFY CODIGO_SEGURIDAD VARCHAR2(8 byte)
       *
ERROR at line 2:
ORA-01439: column to be modified must be empty to change datatype

Para resolver este inconveniente, puedes utilizar el siguiente método, para evitar cambiar el orden de las columnas en la tabla.

Pre-requisitos:
  1. La columna a modificar no posee un constraints de NOT NULL. Si fuera así, debe desactivarse inicialmente el mismo.
  2. La modificación en la tabla, puede ocasionar objetos inválidos en el esquema, por dependencias con el objeto. Si es posible, genere una ventana de mantenimiento para evitar errores con el usuario final.
Post-ejecución:
  1. Activar constraints en la tabla que hayan sido deshabilitados.
  2. Verifique que no existen objetos inválidos. Previamente sería adecuado validar las dependencias en el objecto y determinar, cuáles objetos podrían quedar inválidos con el cambio. Para obtener las dependencias en la tabla, puedes utilizar el paquete DBMS_UTILITY, como se detalla a continuación:
set serveroutput on;
exec dbms_utility.get_dependency('TABLE', '&Esquema','&TABLA');
Ahora si, vamos al problema. Nuestra tabla es la siguiente:

SQL> desc CND_FACTURA
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER(38)
 ....
 COD_MONEDA                                         VARCHAR2(3)
 IND_IMPRESA                                        VARCHAR2(1)
 COD_FONDO                                          NUMBER(3)
 NOM_INQUILINO                                      VARCHAR2(150)
 TERCERA_PERSONA                                    VARCHAR2(150)
 NUM_RECIBO_IMPRESO                                 NUMBER(38)
 IND_APROBACION                                     VARCHAR2(1)
 CODIGO_SEGURIDAD                                   NUMBER(8)
 NUM_FACTURA_ATV                                    NUMBER(38)

Paso 1: Vamos a agregar una nueva columna con el tipo de dato que necesito migrar.

SQL> alter table CND_FACTURA add codigo_seguridad_original varchar2(8);

Table altered.

Paso 2: Vamos a actualizar los valores ya existentes en la columna que necesito modificar en la columna que hemos agregado.

SQL> update CND_FACTURA set codigo_seguridad_original=codigo_seguridad;

3315 rows updated.

Paso 3: Ahora actualizamos a NULL los valores para la columna que necesito migrar.

SQL> update cnd_factura set codigo_seguridad=null;

3315 rows updated.

Paso 4: Modificar a la nueva precisión o tipo de dato la columna con el problema.

SQL> ALTER TABLE CND_FACTURA MODIFY CODIGO_SEGURIDAD VARCHAR2(8 byte);

Table altered.


Paso 5: Actualizar la columna modificada, con los valores originales que contenía la misma.

SQL> update CND_FACTURA set codigo_seguridad=codigo_seguridad_original;

3315 rows updated.

SQL> commit;

Commit complete.

SQL> select count(*) from  CND_FACTURA where codigo_seguridad is not null;

  COUNT(*)
----------
       132

Paso 6: Remover la columna que habíamos agregado al inicio del ejercicio.

SQL> alter table CND_FACTURA drop column codigo_seguridad_original;

Table altered.

SQL> desc CND_FACTURA
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER(38)
 ID_CUOTA_CONDOMINAL                       NOT NULL NUMBER(38)
 FEC_FACTURA                               NOT NULL DATE
 FEC_VENCIMIENTO                           NOT NULL DATE
 FEC_CANCELACION                                    DATE
 IND_ESTADO                                NOT NULL VARCHAR2(1)
 MON_FACTURA                               NOT NULL NUMBER(38,2)
 SALDO_FACTURA                                      NUMBER(38,2)
 INT_MOROCIDAD                                      NUMBER(38,2)
 TIPO_FACTURA                              NOT NULL VARCHAR2(1)
 NUM_RECIBO_CANCELACION                             NUMBER(38)
 ID_USUARIO_MODIFICA                       NOT NULL VARCHAR2(35)
 FEC_MODIFICACION                          NOT NULL DATE
 IND_ENVIADO_CORREO                        NOT NULL VARCHAR2(1)
 OBS_FACTURA                                        VARCHAR2(255)
 ID_INQUILINO                                       NUMBER(38)
 COD_MONEDA                                         VARCHAR2(3)
 IND_IMPRESA                                        VARCHAR2(1)
 COD_FONDO                                          NUMBER(3)
 NOM_INQUILINO                                      VARCHAR2(150)
 TERCERA_PERSONA                                    VARCHAR2(150)
 NUM_RECIBO_IMPRESO                                 NUMBER(38)
 IND_APROBACION                                     VARCHAR2(1)
 CODIGO_SEGURIDAD                                   VARCHAR2(8)
 NUM_FACTURA_ATV                                    NUMBER(38)

SQL>

Estado resuelto.


1 comentario:

  1. Excelente, justo tuve este problema y estaba entre esta misma opcion o crear otra tabla. Simple y efectivo!

    ResponderEliminar

Te agradezco tus comentarios. Te esperamos de vuelta.

Todos los Sábados a las 8:00PM

Optimismo para una vida Mejor

Optimismo para una vida Mejor
Noticias buenas que comentar