No puede eliminar la restricción inexistente y tampoco puede crearla


16

Mientras probaba algunos scripts de migración con una copia de los datos de producción (los scripts funcionan bien con los datos de desarrollo), encontré una situación curiosa. Una CONSTRAINT ha cambiado, así que estoy emitiendo comandos DROP + ADD:

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;

ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
    CONTROL_ID,
    CALLE_AYTO_DUPL
)
ENABLE;

El comando DROP funcionó bien pero el ADD falló. Ahora estoy en un círculo vicioso. No puedo descartar la restricción porque no existe (la caída inicial funcionó como se esperaba):

ORA-02443: No se puede eliminar la restricción: restricción inexistente

Y no puedo crearlo porque el nombre ya existe:

ORA-00955: el nombre ya lo utiliza un objeto existente

Escribo A_DUP_CALLE_UK1en el cuadro de búsqueda del desarrollador SQL y ... ¡ahí está! Propietario, nombre de la tabla, tablescape ... todo coincide: no es un objeto diferente con el mismo nombre, es mi restricción original. La tabla aparece en los detalles de la restricción, pero la restricción no aparece en los detalles de la tabla.

Mis preguntas:

  • ¿Cuál es la explicación de esto?
  • ¿Cómo puedo asegurarme de que no sucederá cuando realizo la actualización real en el servidor en vivo?

(El servidor es 10g XE, no tengo suficiente reputación para crear la etiqueta).


¿Tal vez se creó como otro tipo de objeto y no como una restricción única? Quizás un índice único ...
Marian

¿Se pudo ejecutar la creación inicial con comillas alrededor del nombre de la tabla? Esto haría que el nombre distinga entre mayúsculas y minúsculas. Si es así, podría caer con comillas y el mismo caso.
Adam Butler

Respuestas:


13

Supongo que diría que Marian tiene razón y esto es causado por un índice y una restricción únicos que tienen el mismo nombre, por ejemplo:

create table t( k1 integer, k2 integer, 
                constraint u1 unique(k1,k2) using index(create unique index u1 on t(k1,k2)),
                constraint u2 unique(k2,k1) using index u1);

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

alter table t drop constraint u1;

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

Normalmente, cuando agrega una restricción única, se crea un índice único con el mismo nombre, pero el índice y la restricción no son lo mismo. ¡Eche un vistazo all_indexespara ver si hay un índice llamado A_DUP_CALLE_UK1e intente averiguar si algo más lo utiliza antes de soltarlo!


Este fue el problema. El archivo de volcado generado por el expcomando contiene una CREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...declaración que no está presente en el conjunto de scripts original.
Álvaro González el

6

Parece muy extraño

Tu puedes correr:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

para verificar si de qué tipo de objeto se queja Oracle. Luego puede ejecutar la declaración DROP apropiada para eso.

Lo único que se me ocurre es dejar caer la tabla por completo DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTSpara deshacerse de todo lo que pertenece a esa tabla y luego volver a crearla por completo.

Si la tabla contiene datos valiosos, puede hacer una copia de seguridad antes:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

Una vez que haya recreado la mesa, puede hacer

INSERT INTO A_DUP_CALLE (col1, col2, col3) 
SELECT col1, col2, col3
FROM old_data

para restaurar los datos


4

Hace unos minutos tuve el mismo problema ... y encontré una explicación.

Al crear una clave primaria, Oracle crea dos objetos: una restricción y un índice que controla la parte "ÚNICA".

Al soltar la restricción, el índice permanece allí, usando el mismo nombre del índice, por lo que si ejecuta solo

alter table t drop constraint u1;

Solo dejarás caer la restricción. Para soltar el índice, deberá ejecutar

drop index u1;

Esto debería hacer el trabajo. Alternativamente, puede ejecutar ambos comandos al mismo tiempo con el comando

alter table t drop constraint u1 including indexes;

cual db? incluyendo no funciona en Oracle
Derick

1

La restricción de clave principal viene con el índice. Cae la restricción pero no el índice. Cheque:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

y ya ves OBJECT_TYPEes INDEX.

Así que ambos:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;

1

Hacer esto

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

Funcionará.

IMAGEN: ingrese la descripción de la imagen aquí


No, no funcionará. Su declaración es exactamente la misma declaración que la primera declaración en la pregunta:ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_with_no_name

Funcionó en realidad. Estaba teniendo el mismo problema desde hoy al mediodía, y buscando la solución me encontré con esto. A veces, las CONSTRAINTS pueden haberse creado de forma sensible a mayúsculas y minúsculas, en cuyo caso, deberá colocar el nombre de la restricción entre comillas dobles cuando lo suelte.
Sachin

Y funcionó para mí. No había nombrado las restricciones explícitamente, por lo que el sistema le dio su propio nombre generado Relationship142y otro nombre de NOT NULLrestricción se le dio SYS_C0015910. Por SYS_C0015910lo tanto, se eliminó con éxito con una simple consulta ALTER, pero Relationship142necesitaba COTIZACIONES DOBLES
Sachin

1
El que creó las restricciones utilizando comillas dobles, por ejemplo: alter table ... add constraint "Relationship143" ... "Relationship143"es de hecho un nombre diferente al RELATIONSHIP143. Pero "RELATIONSHIP143"y RELATIONSHIP143son idénticos
a_horse_with_no_name

2
Oracle (la base de datos) nunca creará un nombre como "Relationship143"propio. Probablemente fue una de sus herramientas que hizo esto. De todos modos: tal como está, su respuesta es simplemente incorrecta en el contexto de la pregunta original.
a_horse_with_no_name
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.