2010-03-03 10 views
13

que tenía una restricción en una tabla haceEncontrar restricción fantasma de la base de datos Oracle


CREATE TABLE "USERSAPPLICATIONS" (
    "USERID" NUMBER NOT NULL , 
    "APPLICATIONNAME" VARCHAR2 (30) NOT NULL , 
CONSTRAINT "PK_USERSAPPLICATIONS" PRIMARY KEY ("USERID","APPLICATIONNAME") 
) 
/

Dos semanas he modificado la tabla, añadí algunas columnas, eliminado los "PK_USERSAPPLICATIONS" restricción y ha añadido una clave sustituta. Puedo ver en Oracle SQL Developer que la restricción PK_USERSAPPLICATIONS ya no existe.

Independientemente de eso, cuando intento agregar dos entradas con la misma combinación usuario/applicationName, me sale un error


SQL Error: ORA-00001: unique constraint (ACCOUNTMP1.PK_USERSAPPLICATIONS) violated 
00001. 00000 - "unique constraint (%s.%s) violated" 
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key. 
      For Trusted Oracle configured in DBMS MAC mode, you may see 
      this message if a duplicate entry exists at a different level. 
*Action: Either remove the unique restriction or do not insert the key. 

Cuando ejecute la instrucción


SELECT * 
FROM user_cons_columns 
WHERE constraint_name = 'PK_USERSAPPLICATIONS' 

consigo cero filas . ¿Como puede ser? Oracle no debería tener ningún conocimiento de la restricción PK_USERSAPPLICATIONS, ya que se ha eliminado hace unas semanas, y tampoco puedo verla en la base de datos.

Respuesta

30

¿Todavía tiene el índice que utilizó esa restricción? Porque a menos que haya incluido la cláusula DROP INDEX cuando eliminó la restricción, seguirá allí. Comience con

SELECT * 
FROM user_indexes 
WHERE index_name = 'PK_USERSAPPLICATIONS' 
/

Alternativamente,

select index_name 
from user_indexes 
where table_name = 'USERSAPPLICATIONS' 
and uniqueness='UNIQUE' 
/

o

select index_name 
from user_ind_columns 
where table_name = 'USERSAPPLICATIONS' 
and column_name in ('USERID' ,'APPLICATIONNAME') 
/

edición

Prueba de concepto

SQL> create table t23 (id number not null, alt_key varchar2(10) not null) 
    2/

Table created. 

SQL> create unique index t23_idx on t23 (id) 
    2/

Index created. 

SQL> alter table t23 add constraint t23_pk primary key (id) using index 
    2/

Table altered. 

SQL> insert into t23 values (1, 'SAM I AM') 
    2/

1 row created. 

SQL> insert into t23 values (1, 'MR KNOX') 
    2/
insert into t23 values (1, 'MR KNOX') 
* 
ERROR at line 1: 
ORA-00001: unique constraint (APC.T23_PK) violated 

SQL> 

Entonces la restricción funciona. ¿Qué sucede si lo dejamos caer sin la cláusula DROP INDEX?

SQL> alter table t23 drop constraint t23_pk 
    2/

Table altered. 

SQL> insert into t23 values (1, 'MR KNOX') 
    2/
insert into t23 values (1, 'MR KNOX') 
* 
ERROR at line 1: 
ORA-00001: unique constraint (APC.T23_IDX) violated 


SQL> 

Observe el cambio sutil en el mensaje de error. La segunda falla hace referencia al nombre del índice, mientras que el mensaje original hace referencia a la restricción. Si el nombre del índice es el mismo que el nombre de la restricción, sería difícil diagnosticar esto.

Si no preescribe explícitamente el índice único, el comportamiento predeterminado de Oracle es crear un índice no exclusivo. En consecuencia, abandonar la restricción sin soltar el índice no causa este problema. (Tenga en cuenta que este comportamiento es cierto de 11g. Supongo, pero no puedo estar seguro, que también es así en versiones anteriores).

+0

+1. Spot on. Nunca pensé de esa manera. – Guru

+0

Respuesta muy buena y completa. Eso fue todo - estúpidamente el índice fue nombrado exactamente como la restricción en mi caso. – simon

+0

Gracias. Después de encontrar el índice, lo dejo usando otro script DROP INDEX PK_USERSAPPLICATIONS; – Coisox

1

Intente comprobar el índice de estas columnas. En algunos casos, el índice asociado a la restricción no se descarta después de la eliminación de la restricción

Cuestiones relacionadas