2010-03-03 5 views
13

j'avais une contrainte dans une tabletrouver contrainte fantôme à partir d'Oracle DB


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

Il y a deux semaines j'ai modifié le tableau, ajouté quelques colonnes, la contrainte « supprimé PK_USERSAPPLICATIONS » et a ajouté une clé de substitution. Je peux voir dans Oracle SQL Developer que la contrainte PK_USERSAPPLICATIONS n'existe plus.

Indépendamment de cela, lorsque je tente d'ajouter deux entrées avec la même combinaison ID utilisateur/applicationName, je reçois une erreur


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. 

Quand j'exécutez l'instruction


SELECT * 
FROM user_cons_columns 
WHERE constraint_name = 'PK_USERSAPPLICATIONS' 

Je reçois aucune ligne . Comment cela peut-il être? Oracle ne devrait avoir aucune connaissance de la contrainte PK_USERSAPPLICATIONS car elle a été supprimée il y a déjà plusieurs semaines, et je ne la vois pas non plus dans la base de données.

Répondre

30

Avez-vous toujours l'index qui a été utilisé par cette contrainte? Parce que si vous avez inclus la clause DROP INDEX lorsque vous avez supprimé la contrainte, il sera toujours là. Commencez par

SELECT * 
FROM user_indexes 
WHERE index_name = 'PK_USERSAPPLICATIONS' 
/

Alternativement,

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

ou

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

modifier

Preuve de concept

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> 

Donc la contrainte fonctionne. Que se passe-t-il si nous l'abandonnons sans la clause 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> 

Notez la modification subtile dans le message d'erreur. Le deuxième échec fait référence au nom de l'index, tandis que le message d'origine fait référence à la contrainte. Si le nom de l'index est le même que le nom de la contrainte, il sera difficile de le diagnostiquer.

Si vous ne précisez pas explicitement l'index unique, le comportement par défaut d'Oracle consiste à créer un index non unique. Par conséquent, abandonner la contrainte sans supprimer l'index ne provoque pas ce problème. (Gardez ce comportement vrai de 11g Je présume - mais je ne peux pas en être sûr - que c'est aussi le cas dans les versions antérieures).

+0

+1. Spot sur. Je n'ai jamais pensé comme ça. – Guru

+0

Très bonne et approfondie réponse. C'était ça - bêtement l'index a été nommé exactement comme la contrainte dans mon cas. – simon

+0

Merci. Après avoir trouvé l'index, je l'abandonne en utilisant un autre script DROP INDEX PK_USERSAPPLICATIONS; – Coisox

1

Essayez de vérifier l'index de ces colonnes. Dans certains cas, l'index associé à la contrainte n'est pas supprimé après la suppression de la contrainte

Questions connexes