Archiwa tagu: Oracle

Duplikaty w tabeli

Jak wiadomo posiadanie zduplikowanych wierszy narusza zasady ACID więc staramy się ich wystrzegać. Oczywiście po pierwsze należy się dobrze zastanowić dlaczego duplikaty się pojawiły. Program który dane wpisuje do tablic widocznie posiada jakiś błąd – należy go znaleźć i poprawić. Po poprawieniu programu można przejść do naprawiania istniejących danych na bazie.

Wypisanie zduplikowanych rekordów:

SELECT c1, c2, c3, …, cn, count(*) FROM TEST group by c1, c2, c3, …., cn HAVING count(*) > 1;

albo tak:

SELECT * FROM test WHERE ROWID NOT IN (SELECT MIN (ROWID) FROM test GROUP BY c1, c2, c3, …, cn);

Mój ulubiony sposób usunięcia rekordów zduplikowanych bazuje na drugim z powyższych SELECT’ów:

DELETE FROM test WHERE ROWID NOT IN (SELECT MIN (ROWID)
FROM test GROUP BY coulmn1, column2, column3);

Podoba mi sie ze względu na swoją prostotę i wykorzystanie dobrodziejstwa Oracle jakim jest pseudokolumna ROWID.

Polecam jeszcze uwadze dodatkowy sposób o którym rzadko ktokolwiek wspomina – utworzenie tabeli na nowo z samymi prawidłowymi rekordami.

CREATE TABLE test_tmp AS
SELECT distinct c1, c2, c3… FROM test;

DROP TABLE test; — usuniecie tablicy źdródłowej

RENAME TEST_TMP TO TEST; — zmiana nazwy tabelki tymczasowej na źródłową

Metoda jest o wiele szybsza niż inne jesli mamy doczynienia z dużą liczba rekordów w tablicy. Przy tradycyjnym kasowaniu rekordów za pomocą DELETE Oracle przechowuje sobie dane na wypadek ROLLBACK w tablicy UNDO – przez to takie usuwanie trwa dłuzej. Usuwanie za pomocą utworzenia nowej tabeli z samymi dobrymi rekordami jest szybsze, ale trzeba pamiętać, że nie zawsze to jest to czego chcemy – rekordy mogą być powiązane CONSTRAINT’ami z którymi trzeba będzie sobie poradzić oraz niektórzy chcieliby jednak mieć możliwość zrobienia ROLLBACK gdyby stwierdzili, że zaszła pomyłka – w przypadku tego sposobu nie ma już możliwości ROLLBACK.

Jest więcej sposobów na radzenie sobie z duplikatami w tablicach w bazach od Oracle – odsyłam do guru: Burleson’a.