ORA-30926: impossibilidade de obter um conjunto estável de linhas nas tabelas de origem

Eu estou recebendo

ORA-30926: incapaz de obter um conjunto estável de filas nas tabelas de fontes

na seguinte consulta:

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

I'executei a table_1 que tem dados e também I'executei a consulta interna (src) que também tem dados.

Porque viria este erro e como pode ser resolvido?

Solução

Isso geralmente é causado por duplicatas na consulta especificada na cláusula USING. Isto provavelmente significa que TABLE_A é uma tabela pai e o mesmo ROWID é retornado várias vezes.

Você poderia resolver o problema rapidamente usando um DISTINCT na sua consulta (na verdade, se 'Y' é um valor constante que você não'nem precisa colocá-lo na consulta).

Assumindo que sua consulta está correta (don't know your tables) você poderia fazer algo como isto:

  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';
Comentários (3)

Você'provavelmente está tentando atualizar a mesma linha da tabela de destino várias vezes. Eu acabei de encontrar o mesmo problema em uma declaração de fusão que desenvolvi. Certifique-se que sua atualização não toque o mesmo registro mais de uma vez na execução da fusão.

Comentários (1)

Como resolver problemas de erros do ORA-30926? (Doc ID 471956.1)

  1. Identificar a declaração de falha

    alterar eventos do conjunto de sessões '30926 trace name errorstack level 3';

ou

alterar eventos do sistema '30926 trace name errorstack off';

e observe os arquivos .trc no UDUMP quando ele ocorrer.

  1. Tendo encontrado a instrução SQL, verifique se ela está correta (talvez usando o plano de explicação ou tkprof para verificar o plano de execução da consulta) e analise ou compute estatísticas nas tabelas em questão se isso não tiver sido feito recentemente. Reconstruir (ou deixar cair/recriar) índices também pode ajudar.

3.1) A instrução SQL é uma MERGE? avalia os dados devolvidos pela cláusula USING para garantir que não existem valores duplicados no join. Modifique a instrução merge para incluir uma cláusula determinística onde

3.2) Esta é uma declaração UPDATE através de uma vista? Em caso afirmativo, tente preencher o resultado da view em uma tabela e tente atualizar a tabela diretamente.

3.3) Há um gatilho em cima da mesa? Tente desativá-lo para ver se ele ainda falha.

3.4) A declaração contém uma visão não fusível em um 'IN-Subquery'? Isto pode resultar na devolução de linhas duplicadas se a consulta tiver um "FOR UPDATE" clause. Veja o Bug 2681037

3.5) A tabela tem colunas não utilizadas? Deixar cair estas colunas pode evitar o erro.

  1. Se a modificação do SQL não cura o erro, o problema pode ser com a tabela, especialmente se houver linhas encadeadas. 4.1) Execute a instrução 'ANALYZE TABLE VALIDATE STRUCTURE CASCADE' em todas as tabelas usadas no SQL para ver se há alguma corrupção na tabela ou em seus índices. 4.2) Verifique e elimine qualquer CHAINED ou ROWS migrado na tabela. Existem maneiras de minimizar isto, tais como a configuração correta de PCTFREE. Use a Nota 122020.1 - Encadeamento e Migração de Linhas 4.3) Se a tabela for adicionalmente Organizado Índice Organizado, veja: Nota 102932.1 - Monitorização de Linhas em cadeia nas IOTs
Comentários (0)