it-swarm.dev

ORA-01502: Indeks lub partycja takiego indeksu jest w stanie użytecznym

Mam tabelę w mojej bazie danych Oracle, gdzie

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

daje

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

Próbuje usunąć zduplikowane wiersze

delete myTable where pkcol = 1;

Wydajność:

ORA-01502: indeks „MYTABLE.PK_MT” lub partycja takiego indeksu jest w stanie użytkowym.

Używam Oracle.DataAccess.Client.OracleBulkCopy do wypełnienia tabeli.

O ile rozumiem dokumentację z Oracle PODSTAWOWE KLUCZOWE ograniczenia musiały zostać sprawdzone.

Oczywiście nie są sprawdzane, co znalazłem, wykonując dwa razy z rzędu tę samą kopię zbiorczą, która zakończyła się duplikatem we wszystkich wierszach.

Teraz używam go dopiero po usunięciu wszystkich wierszy i używam tabeli z podobnym kluczem podstawowym jak źródło. W rezultacie nie oczekuję żadnych problemów.

Ale osadzone głęboko w moich skryptach MS Build, mam tylko 2 duplikaty z 2210 wierszy.

Wydaje mi się, że ignorowanie klucza podstawowego jest przede wszystkim wyraźnym błędem. Żadna z funkcji Bulkcopy nie powinna umożliwiać ignorowania ograniczeń klucza podstawowego.

Edycja:

W międzyczasie odkryłem, że 2 sprzeczne wiersze były normalnie wstawiane przez jakiś skrypt przed wywołaniem kopii zbiorczej. Problem sprowadza się do mojego znanego problemu, że zbiorcza kopia nie sprawdza tutaj kluczy podstawowych.

6
bernd_k

Z dokumentacja, do której linkujesz :

UNIKALNE ograniczenia są weryfikowane, gdy indeksy są przebudowywane na końcu ładowania. Indeks pozostaje w stanie Indeksu nieużywalnego, jeśli narusza ograniczenie UNIKALNE.

Sposób, w jaki to czytam, to samo dotyczy PRIMARY KEY ograniczenia, choć sformułowanie jest trochę niejednoznaczne. Możesz nie lubić tego zachowania, ale nie jest to „błąd”, ponieważ zachowuje się on zgodnie z przeznaczeniem - i istnieją inne sposoby kończenie z takim rodzajem „zepsutego” ograniczenia.

Zobacz ten post OTN , aby uzyskać więcej informacji i podejście, które może działać lepiej dla Ciebie przy użyciu pl/sql i forall ... save exceptions.

W obliczu podobnego problemu.

Jeśli chcesz pozbyć się błędu, wykonaj:

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

Spowoduje to wyświetlenie ALTER INDEX ... REBUILD; instrukcje dla wszystkich indeksów „bezużytecznych”. Uruchom je, aby indeksy mogły być ponownie „użyteczne”.

(Bezwstydnie skopiowane z: http://www.squaredba.com/ora-01502-index-or-partition-of-such-index-is-in-unusable-state-145.html : -))

8
Frosty Z