Al lanzar una sentencia de alteración de tabla (ALTER TABLE) podemos encontrar con el ORA-30556 que nos indica que un índice asociado a la tabla impide la alteración.
Índice
El error debería ser algo parecido a esto:
Error que empieza en la línea: 5 del comando :
ALTER TABLE XXX YYY varchar2(3) /*NOT NULL*/
Informe de error -
ORA-30556: hay un índice funcional o de unión de bitmap definido en la columna que se va a modificar
30556. 00000 - "either functional or bitmap join index is defined on the column to be modified"
*Cause: An ALTER TABLE MODIFY COLUMN was issued on a column on which
either a functional index or bitmap join index exists.
*Action: Drop the functional or bitmap join index before attempting to modify the column.
Si éste es vuestro caso tendréis que investigar los índices asociados a la tabla que estáis intentando modificar. El ORA-30556 es bastante explicito y hace referencia a los índices funcionales (FUNCTION). Con la siguiente sentencia podremos ver todos los índices de este tipo y localizar los que pertenecen a la tabla en cuestión:
select table_name, index_name, index_typefrom user_indexeswhere index_type like 'FUNCTION%' order by table_name, index_name;
Con esto sabréis que índices están asociados a esa tabla. A continuación os dejo las dos posibles soluciones al problema (si sabéis cuál es el índice problematico podéis lanzar la solución solo en ese índice concreto, de lo contrario podéis lanzarlo en todos ellos).
1. Deshabilitar el índice
Podéis deshabilitar el índice problematico de la siguiente forma:
ALTER INDEX <NOMBRE_ÍNDICE> ON <NOMBRE_TABLA> DISABLE;
Una vez deshabilitado podemos lanzar nuestro ALTER TABLE y, una vez alterada correctamente, volver a habilitar el índice:
ALTER INDEX <NOMBRE_ÍNDICE> ON <NOMBRE_TABLA> REBUILD;
2. Eliminar y recrear el índice
En caso de que la primera solución no nos funcione correctamente podemos intentarlo de esta segunda forma.
La solución ideal sería eliminar los índices vinculados para siempre, pero como en ocasiones esto no os posible (o no sabemos las implicaciones que eso tendría) vamos a lanzar esta sentencia con el nombre de índice afectado:
SELECT DBMS_METADATA.GET_DDL('INDEX', '<NOMBRE_ÍNDICE>') FROM USER_INDEXES;
Esto os devolverá la sentencia de creación del índice. Anotadla y no la perdáis.
Una vez hecho esto, la solución es muy sencilla:
- Eliminad el índice
- Lanzad el ALTER TABLE que os había generado el error (ahora no os dará problemas)
- Volved a crear el índice
La eliminación del índice es muy sencilla:
DROP INDEX <NOMBRE_ÍNDICE>;
Con estas dos opciones deberíais ser capaces de solventar el error.