ORA-30926: impossibile ottenere un set stabile di righe nelle tabelle di origine


129

Sto ottenendo

ORA-30926: impossibile ottenere un set stabile di righe nelle tabelle di origine

nella seguente query:

  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';

Ho eseguito table_1ha dati e anche ho eseguito la query inside ( src) che ha anche dati.

Perché dovrebbe verificarsi questo errore e come può essere risolto?

Risposte:


202

Questo di solito è causato da duplicati nella query specificata nella clausola USING. Questo probabilmente significa che TABLE_A è una tabella padre e lo stesso ROWID viene restituito più volte.

È possibile risolvere rapidamente il problema utilizzando un DISTINCT nella query (in effetti, se "Y" è un valore costante, non è nemmeno necessario inserirlo nella query).

Supponendo che la tua query sia corretta (non conosci le tue tabelle) potresti fare qualcosa del genere:

  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
Questo è probabilmente il motivo per cui altri approcci (per me) hanno anche restituito altri errori per me (come "procedura, funzione, pacchetto o tipo non sono consentiti qui" e "Impossibile modificare una colonna che associa a un errore di tabella non conservato da chiave durante il tentativo di inserire in una vista '). ~ Se aiuta qualcun altro, ho avuto lo stesso errore anche dopo aver aggiunto distinto fino a quando non ho riorganizzato i join della mia query interna, quindi ho iniziato con la tabella che stava restituendo più di una riga e l'interno era unito da lì ... se quello ha senso.
jinglesthula,

40

Probabilmente stai cercando di aggiornare più volte la stessa riga della tabella di destinazione. Ho appena riscontrato lo stesso problema in una dichiarazione di unione che ho sviluppato. Assicurati che il tuo aggiornamento non tocchi lo stesso record più di una volta nell'esecuzione della fusione.


1
+1, grazie, mi è appena successo su una tabella di destinazione con un piccolo numero di duplicati (almeno in base alle chiavi utilizzate nell'unione).
tbone,

6

Come risolvere gli errori ORA-30926? (ID documento 471956.1)

1) Identificare la dichiarazione non riuscita

modifica gli eventi del set di sessioni '30926 nome traccia errore livello 3';

o

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

e cerca i file .trc in UDUMP quando si verifica.

2) Dopo aver trovato l'istruzione SQL, verificare se è corretta (magari utilizzando spiegazione del piano o tkprof per controllare il piano di esecuzione della query) e analizzare o calcolare le statistiche sulle tabelle interessate se ciò non è stato fatto di recente. Ricostruire (o far cadere / ricreare) gli indici può anche aiutare.

3.1) L'istruzione SQL è MERGE? valutare i dati restituiti dalla clausola USING per assicurarsi che non vi siano valori duplicati nel join. Modifica l'istruzione di unione in modo da includere una clausola where deterministica

3.2) È un'istruzione UPDATE tramite una vista? In tal caso, prova a popolare il risultato della vista in una tabella e prova ad aggiornare direttamente la tabella.

3.3) C'è un grilletto sul tavolo? Prova a disabilitarlo per vedere se fallisce ancora.

3.4) La dichiarazione contiene una vista non unificabile in una "sottoquery"? Ciò può comportare la restituzione di righe duplicate se la query ha una clausola "FOR UPDATE". Vedi Bug 2681037

3.5) La tabella ha colonne inutilizzate? La caduta di questi potrebbe impedire l'errore.

4) Se la modifica dell'SQL non risolve l'errore, il problema potrebbe riguardare la tabella, soprattutto se sono presenti righe concatenate. 4.1) Eseguire l'istruzione 'ANALYZE TABLE VALIDATE STRUCTURE CASCADE' su tutte le tabelle utilizzate nell'SQL per vedere se vi sono corruzioni nella tabella o nei suoi indici. 4.2) Verificare ed eliminare eventuali file CHAINED o migrati sulla tabella. Ci sono modi per minimizzare questo, come l'impostazione corretta di PCTFREE. Utilizzare la nota 122020.1 - Concatenamento delle righe e migrazione 4.3) Se la tabella è ulteriormente organizzata in modo indice, consultare: Nota 102932.1 - Monitoraggio delle righe concatenate sugli IOT


5

Ha avuto l'errore oggi su un 12c e nessuna delle risposte esistenti era adatta (nessun duplicato, nessuna espressione non deterministica nella clausola WHERE). Il mio caso era correlato a quell'altra possibile causa dell'errore, secondo il testo del messaggio di Oracle (enfasi di seguito):

ORA-30926: impossibile ottenere un set stabile di righe nelle tabelle di origine
Causa : impossibile ottenere un set stabile di righe a causa della grande attività dml o di una clausola where non deterministica.

L'unione faceva parte di un batch più grande ed è stata eseguita su un database live con molti utenti simultanei. Non è stato necessario modificare la dichiarazione. Ho appena eseguito il commit della transazione prima della fusione, quindi ho eseguito la fusione separatamente e ho eseguito nuovamente il commit. Quindi la soluzione è stata trovata nell'azione suggerita del messaggio:

Azione: rimuovere eventuali clausole where non deterministiche ed emettere nuovamente il dml .


Stavo ricevendo quel messaggio di errore durante l'importazione di DataPump tramite la rete (utilizzando un NETWORK_LINKparametro che si collega direttamente al database di origine) durante la fase di raccolta delle statistiche e probabilmente la tua nota evidenziata lo spiega. Fortunatamente sono state interessate solo le statistiche.
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.

Questo errore si è verificato per me a causa di record duplicati (16 KB)

Ho provato con unico ha funzionato .

ma ancora una volta quando ho provato a unire senza lo stesso problema si è verificato la seconda volta era dovuto impegnarsi

dopo l'unione se il commit non viene eseguito verrà mostrato lo stesso errore.

Senza univoco, la query funzionerà se viene assegnato il commit dopo ogni operazione di unione.


-1

Un ulteriore chiarimento sull'uso di DISTINCT per risolvere l'errore ORA-30926 nel caso generale:

È necessario assicurarsi che l'insieme di dati specificato dalla clausola USING () non abbia valori duplicati delle colonne di join , ovvero le colonne nella clausola ON () .

Nell'esempio di OP in cui la clausola USING seleziona solo una chiave, è stato sufficiente aggiungere DISTINCT alla clausola USING. Tuttavia, nel caso generale, la clausola USING può selezionare una combinazione di colonne chiave da abbinare e attribuire colonne da utilizzare nella clausola UPDATE ... SET. Pertanto, nel caso generale, l'aggiunta di DISTINCT alla clausola USING consentirà comunque diverse righe di aggiornamento per le stesse chiavi, nel qual caso si otterrà comunque l'errore ORA-30926.

Questa è un'elaborazione della risposta di DCookie e il punto 3.1 nella risposta di Tagar, che dalla mia esperienza potrebbe non essere immediatamente ovvio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.