it-swarm-eu.dev

ORA-01502: index nebo oddíl takového indexu je v použitelném stavu

Mám tabulku v databázi Oracle, kde

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

výnosy

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

Pokouší se odstranit duplicitní řádky

delete myTable where pkcol = 1;

Výnosy:

ORA-01502: index 'MYTABLE.PK_MT' nebo oddíl takového indexu je v použitelném stavu.

K vyplnění tabulky používám Oracle.DataAccess.Client.OracleBulkCopy.

Pokud chápu dokumentaci od Oracle , musela být zkontrolována omezení PRIMARY KEY.

Očividně nejsou kontrolovány, jak jsem zjistil tím, že jsem provedl stejnou hromadnou kopii dvakrát za sebou, která skončila duplikáty ve všech řádcích.

Teď to používám pouze po smazání všech řádků a používám tabulku s podobným primárním klíčem jako zdroj. V důsledku toho neočekávám žádné problémy.

Ale vložené hluboko do mých skriptů MS Build, skončím pouhými 2 duplikáty z 2210 řádků.

Myslím, že ignorování primárního klíče je v první řadě jasnou chybou. Žádná Bulkcopy by neměla mít možnost ignorovat omezení primárních klíčů.

Upravit:

Mezitím jsem zjistil, že 2 konfliktní řádky byly normálně vloženy nějakým skriptem před hromadným kopírováním. Problém se zmenšuje na můj známý problém, že hromadné kopírování zde nekontroluje primární klíče.

6
bernd_k

Z dokumentace, na kterou odkazujete :

UNIQUE omezení se ověřují, když jsou indexy na konci načtení znovu sestaveny. Index je ponechán ve stavu Nepoužitelný index, pokud porušuje omezení UNIQUE.

Způsob, jakým jsem to četl, to samé platí pro omezení PRIMARY KEY, I když formulace je trochu nejednoznačná. Toto chování se vám nemusí líbit, ale nejedná se o „chybu“, protože se chová tak, jak je navrženo - a existuje jiné způsoby skončit s tímto druhem „zlomeného“ omezení.

Viz tento příspěvek OTN pro více informací a přístup, který by pro vás mohl fungovat lépe pomocí pl/sql a forall ... save exceptions.

Tváří v tvář podobnému problému.

Potřebujete-li se pouze této chyby zbavit, proveďte následující kroky:

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

Výstupem bude ALTER INDEX ... REBUILD; příkazy pro všechny „nepoužitelné“ indexy. Spusťte je, aby indexy mohly být znovu „použitelné“.

(Nestydatě zkopírováno z: http://www.squaredba.com/ora-01502-index-or-partition-of-such-index-is-in-unusable-state-145.html : -))

8
Frosty Z