ORA-30926: nie można uzyskać stabilnego zestawu wierszy w tabelach źródłowych


135

staje się

ORA-30926: nie można uzyskać stabilnego zestawu wierszy w tabelach źródłowych

w następującym zapytaniu:

  MERGE INTO table_1 a
      USING 
      (SELECT a.ROWID row_id, 'Y'
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

Uruchomiłem table_1to z danymi, a także uruchomiłem zapytanie wewnętrzne ( src), które również zawiera dane.

Dlaczego pojawił się ten błąd i jak można go rozwiązać?

Odpowiedzi:


206

Zwykle jest to spowodowane duplikatami zapytania określonego w klauzuli USING. To prawdopodobnie oznacza, że ​​TABLE_A jest tabelą nadrzędną i ten sam ROWID jest zwracany kilka razy.

Możesz szybko rozwiązać problem, używając DISTINCT w zapytaniu (w rzeczywistości, jeśli `` Y '' jest wartością stałą, nie musisz nawet wpisywać go w zapytaniu).

Zakładając, że twoje zapytanie jest poprawne (nie znasz swoich tabel), możesz zrobić coś takiego:

  MERGE INTO table_1 a
      USING 
      (SELECT distinct ta.ROWID row_id
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

1
Prawdopodobnie dlatego inne podejścia (dla mnie) zwróciły również inne błędy (takie jak „procedura, funkcja, pakiet lub typ jest tu niedozwolony” i „Nie można zmodyfikować kolumny, która mapuje na błąd tabeli niezachowany kluczem podczas próby wstaw do widoku ”). ~ Jeśli pomoże to komukolwiek innemu, otrzymałem ten sam błąd nawet po dodaniu słowa odrębnego, dopóki nie uporządkowałem złączeń mojego wewnętrznego zapytania, więc zacząłem od tabeli, do której zwracano więcej niż jeden wiersz i stamtąd łączono wewnętrznie ... jeśli tak ma sens.
jinglesthula

41

Prawdopodobnie próbujesz wielokrotnie aktualizować ten sam wiersz tabeli docelowej. Właśnie napotkałem ten sam problem w instrukcji scalania, którą opracowałem. Upewnij się, że aktualizacja nie dotyka tego samego rekordu więcej niż raz podczas wykonywania scalania.


3
+1, dzięki, to właśnie mi się przydarzyło na stole docelowym z niewielką liczbą duplikatów (przynajmniej na podstawie kluczy użytych do scalenia).
tbone

6

Jak rozwiązywać problemy z ORA-30926? (ID dokumentu 471956.1)

1) Zidentyfikuj niezgodne stwierdzenie

zmień zdarzenia zestawu sesji „30926 nazwa śledzenia errorstack poziom 3”;

lub

alter system set events '30926 trace name errorstack off';

i uważaj na pliki .trc w UDUMP, gdy wystąpią.

2) Po znalezieniu instrukcji SQL sprawdź, czy jest poprawna (na przykład przy użyciu planu wyjaśniania lub tkprof w celu sprawdzenia planu wykonania zapytania) i przeanalizuj lub oblicz statystyki dotyczące odpowiednich tabel, jeśli nie zostało to ostatnio zrobione. Odbudowanie (lub upuszczenie / odtworzenie) indeksów też może pomóc.

3.1) Czy instrukcja SQL jest MERGE? ocenić dane zwrócone przez klauzulę USING, aby upewnić się, że w łączeniu nie ma zduplikowanych wartości. Zmodyfikuj instrukcję merge, aby zawierała deterministyczną klauzulę where

3.2) Czy jest to instrukcja UPDATE za pośrednictwem widoku? Jeśli tak, spróbuj wypełnić wynik widoku w tabeli i spróbuj bezpośrednio zaktualizować tabelę.

3.3) Czy na stole jest wyzwalacz? Spróbuj go wyłączyć, aby sprawdzić, czy nadal się nie powiedzie.

3.4) Czy instrukcja zawiera niemożliwy do scalenia widok w „IN-Subquery”? Może to spowodować zwrócenie zduplikowanych wierszy, jeśli zapytanie zawiera klauzulę „FOR UPDATE”. Zobacz błąd 2681037

3.5) Czy tabela zawiera nieużywane kolumny? Usunięcie ich może zapobiec wystąpieniu błędu.

4) Jeśli modyfikacja kodu SQL nie usunie błędu, problem może dotyczyć tabeli, zwłaszcza jeśli istnieją powiązane wiersze. 4.1) Uruchom instrukcję „ANALYZE TABLE VALIDATE STRUCTURE CASCADE” na wszystkich tabelach używanych w języku SQL, aby sprawdzić, czy w tabeli lub w jej indeksach nie ma żadnych uszkodzeń. 4.2) Sprawdź i wyeliminuj wszystkie WIERSZE ŁAŃCUCHOWE lub migrowane w tabeli. Istnieją sposoby, aby to zminimalizować, takie jak prawidłowe ustawienie PCTFREE. Użyj notatki 122020.1 - Łączenie wierszy i migracja 4.3) Jeśli tabela jest dodatkowo zorganizowana według indeksów, zobacz: Uwaga 102932.1 - Monitorowanie połączonych wierszy na IOT


5

Czy błąd dzisiaj w 12c i żadna z istniejących odpowiedzi nie pasuje (brak duplikatów, brak niedeterministycznych wyrażeń w klauzuli WHERE). Mój przypadek był związany z inną możliwą przyczyną błędu, zgodnie z treścią komunikatu Oracle (podkreślenie poniżej):

ORA-30926: nie można uzyskać stabilnego zestawu wierszy w tabelach źródłowych.
Przyczyna: Nie można uzyskać stabilnego zestawu wierszy z powodu dużej aktywności dml lub niedeterministycznej klauzuli where.

Scalanie było częścią większej partii i zostało wykonane na działającej bazie danych z wieloma równoczesnymi użytkownikami. Nie było potrzeby zmiany oświadczenia. Właśnie zatwierdziłem transakcję przed scaleniem, a następnie osobno przeprowadziłem scalanie i zatwierdziłem ponownie. Tak więc rozwiązanie zostało znalezione w sugerowanej akcji komunikatu:

Akcja: Usuń wszystkie niedeterministyczne klauzule Where i ponownie uruchom dml .


Otrzymałem ten komunikat o błędzie podczas importowania DataPump przez sieć (przy użyciu NETWORK_LINKparametru, który łączy się bezpośrednio ze źródłową bazą danych) na etapie zbierania statystyk, a Twoja podświetlona notatka prawdopodobnie to wyjaśnia. Na szczęście wpłynęło to tylko na statystyki.
Mark Stewart

1
SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 -  "unable to get a stable set of rows in the source tables"
*Cause:    A stable set of rows could not be got because of large dml
           activity or a non-deterministic where clause.
*Action:   Remove any non-deterministic where clauses and reissue the dml.

Ten błąd wystąpił z powodu zduplikowanych rekordów (16 KB)

I starał się wyjątkowy to działało .

ale ponownie, gdy próbowałem scalić bez unikalnego problemu, wystąpił ten sam problem Drugi raz było to spowodowane zatwierdzeniem

po scaleniu, jeśli zatwierdzenie nie zostanie wykonane, zostanie wyświetlony ten sam błąd.

Bez wartości Unique Query będzie działać, jeśli zatwierdzenie zostanie podane po każdej operacji scalania.


0

Dalsze wyjaśnienie dotyczące użycia DISTINCT do rozwiązania błędu ORA-30926 w przypadku ogólnym:

Należy upewnić się, że zestaw danych określony w klauzuli USING () nie zawiera zduplikowanych wartości kolumn łączenia , tj. Kolumn w klauzuli ON () .

W przykładzie OP, gdzie klauzula USING wybiera tylko klucz, wystarczyło dodać DISTINCT do klauzuli USING. Jednak w ogólnym przypadku klauzula USING może wybrać kombinację kolumn kluczy do dopasowania i kolumn atrybutów, które mają być użyte w klauzuli UPDATE ... SET. Dlatego w ogólnym przypadku dodanie DISTINCT do klauzuli USING nadal będzie zezwalać na różne wiersze aktualizacji dla tych samych kluczy, w takim przypadku nadal będzie występował błąd ORA-30926.

To jest rozwinięcie odpowiedzi DCookie i punktu 3.1 w odpowiedzi Tagara, co z mojego doświadczenia może nie być od razu oczywiste.


Nie rozumiem obniżania głosów. To był mój przypadek (wielokolumny) i Unikalne obejście nie przyniosło efektu. Tak więc, jak mówi @Durban_legend, trzeba upewnić się, że nie ma dups (usunąłem niektóre kolumny ID „resztki”), a następnie użyć Distinct i działało. Głosując za tym wyjaśnieniem, ponieważ nie było to od razu oczywiste w przyjętej odpowiedzi.
Diego 1974

0

Nie mogłem tego rozwiązać po kilku godzinach. W końcu po prostu dokonałem selekcji z połączonymi dwiema tabelami, utworzyłem wyodrębnienie i utworzyłem indywidualne instrukcje aktualizacji SQL dla 500 wierszy w tabeli. Brzydkie, ale bije godziny na próby uzyskania zapytania do pracy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.