web-dev-qa-db-fra.com

ORA-01502: l'index ou la partition d'un tel index est dans un problème d'état utilisable

J'ai une table dans ma base de données Oracle, où

select pkcol, count(*) from myTable group by pkcol having count(*) > 1;

les rendements

  PKCOL   COUNT(*)
------- ----------
      1          2
      2          2

Essayer de supprimer les lignes en double

delete myTable where pkcol = 1;

Rendements:

ORA-01502: l'index 'MYTABLE.PK_MT' ou la partition d'un tel index est dans un état utilisable.

J'utilise Oracle.DataAccess.Client.OracleBulkCopy pour remplir le tableau.

Pour autant que je comprends la documentation d'Oracle PRIMARY KEY contraintes devaient être vérifiées.

De toute évidence, ils ne sont pas vérifiés, comme je l'ai constaté en faisant la même copie en bloc deux fois de suite, ce qui s'est terminé par des doublons dans toutes les lignes.

Maintenant, je ne l'utilise qu'après avoir supprimé toutes les lignes et j'utilise une table avec une clé primaire similaire comme source. En conséquence, je n'attends aucun problème.

Mais intégré profondément dans mes scripts MS Build, je me retrouve avec seulement 2 doublons sur 2210 lignes.

Je suppose que ignorer la clé primaire en premier lieu est un bug clair. Aucune copie en bloc ne doit être autorisée à ignorer les contraintes de clé primaire.

Modifier:

Pendant ce temps, j'ai trouvé que les 2 lignes en conflit étaient normalement insérées par un script avant l'appel en bloc. Le problème se réduit à mon problème connu, cette copie en bloc ne vérifie pas les clés primaires ici.

6
bernd_k

De la documentation à laquelle vous liez :

Les contraintes UNIQUES sont vérifiées lorsque les index sont reconstruits à la fin du chargement. L'index est laissé dans un état Index inutilisable s'il viole une contrainte UNIQUE.

Comme je le lis, c'est la même chose pour PRIMARY KEY contraintes bien que le libellé soit un peu ambigu. Vous n'aimerez peut-être pas ce comportement, mais ce n'est pas "un bug" car il se comporte comme prévu - et il y a d'autres façons de se retrouver avec ce genre de contrainte "cassée".

Voir cet article OTN pour plus d'informations et une approche qui pourrait mieux fonctionner pour vous en utilisant pl/sql et forall ... save exceptions.

Face à un problème similaire.

Si vous avez juste besoin de vous débarrasser de l'erreur, faites:

SELECT 'ALTER INDEX '||OWNER||'.'||INDEX_NAME||' REBUILD;'
FROM DBA_INDEXES
WHERE STATUS = 'UNUSABLE';

Cela produira ALTER INDEX ... REBUILD; instructions pour tous les index "inutilisables". Exécutez-les pour que les index puissent à nouveau être "utilisables".

(Copié sans vergogne de: http://www.squaredba.com/ora-01502-index-or-partition-of-such-index-is-in-unusable-state-145.html : -))

8
Frosty Z