web-dev-qa-db-fra.com

ORA-00955 "le nom est déjà utilisé par un objet existant"

J'ai besoin de modifier une PK existante. Par conséquent je laisse tomber un recréer.

ALTER TABLE B DROP CONSTRAINT PK_B;
ALTER TABLE B ADD CONSTRAINT PK_B PRIMARY KEY ("TYP", "NR", "HH", "QUART");

Malheureusement, la dernière déclaration me donnera une erreur ORA-00955

Si je crée la contrainte PK comme elle a été définie à l’origine avec:

ALTER TABLE B ADD CONSTRAINT PK_B PRIMARY KEY ("TYP", "NR", "HH");

tout fonctionne bien.

7
My-Name-Is

Peut-être existe-t-il une INDEX associée au PRIMARY KEY CONSTRAINT, qui porte également le nom PK_B.

Vous pouvez le vérifier comme:

SELECT * FROM USER_INDEXES WHERE TABLE_NAME='<table_name>';

Si c'est vrai, alors faites:

ALTER INDEX "PK_B" RENAME TO "PK_XYZ";

Mise à jour: En ce qui concerne la déclaration ALTER INDEX, quelques points importants mentionnés par Justin dans les commentaires

Oracle crée implicitement un index UNIQUE pour prendre en charge le PRIMARY KEY CONSTRAINT. Depuis, l’index porte le même nom que celui de la clé primaire, et maintenant que la clé primaire est en cours de modification, il est meilleur pour supprimer et recréer l’index de définition de l'ancienne clé primaire.

Ma conclusion:

  • La contrainte de clé primaire est appliquée via un index unique.
  • Si Oracle trouve déjà un index - unique ou non unique - il l’utilise Pour la clé primaire.
  • Si l'index a été créé à l'origine comme non unique, il continuera à afficher __.show comme étant non unique, mais il s'agira en réalité d'un index unique.

Une bonne démonstration et assez détaillée sur d'autres aspects aussi, par Arup: Principales Clés Garantie Unicité? Pensez encore.

14
Lalit Kumar B

J'ai eu le même problème où je devais faire ce qui suit pour supprimer la référence à une table de la vue tout en recréant la base de données à partir de zéro. Je cherchais le même dans les tables et les index en premier.

connect sys/Oracle as sysdba;
select * from all_tables
select * from all_indexes
(finally located the reference in the views)
select * from all_views where view_name like '%WKSTSTATE%';
drop view RUEGEN.WKSTSTATE;
0
donsasikumar