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

129

estou obtendo

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

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

Eu executei table_1ele possui dados e também executei a query interna ( src) que também possui dados.

Por que esse erro ocorreu e como ele pode ser resolvido?

Onipresente
fonte

Respostas:

202

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

Você pode resolver rapidamente o problema usando um DISTINCT na sua consulta (na verdade, se 'Y' for um valor constante, você nem precisará colocá-lo na consulta).

Supondo que sua consulta esteja correta (não conheça suas tabelas), você pode fazer algo assim:

  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';
Pop
fonte
1
Provavelmente, é por isso que outras abordagens (para mim) também retornaram outros erros para mim (como 'procedimento, função, pacote ou tipo não são permitidos aqui' e 'Não é possível modificar uma coluna que mapeia um erro de tabela não preservado por chave ao tentar inserir em uma visualização '). ~ Se isso ajuda outras pessoas, recebi o mesmo erro mesmo depois de adicionar distintas até reorganizar as junções da minha consulta interna, então comecei com a tabela que estava recebendo mais de uma linha retornada e a junção interna a partir daí ... se isso faz sentido.
jinglesthula
40

Você provavelmente está tentando atualizar a mesma linha da tabela de destino várias vezes. Acabei de encontrar o mesmo problema em uma declaração de mesclagem que desenvolvi. Verifique se a atualização não toca no mesmo registro mais de uma vez na execução da mesclagem.

DCookie
fonte
1
+1, obrigado, isso aconteceu comigo em uma tabela de destino com um pequeno número de duplicatas (pelo menos com base nas chaves usadas na mesclagem).
tbone
6

Como solucionar os erros do ORA-30926? (ID do documento 471956.1)

1) Identifique a declaração com falha

alterar eventos do conjunto de sessões '30926 nome do rastreamento errorstack nível 3';

ou

alterar eventos do conjunto do sistema 'nome do rastreio 30926 errorstack off';

e observe os arquivos .trc no UDUMP quando ocorrerem.

2) Após encontrar a instrução SQL, verifique se ela está correta (talvez usando o plano de explicação ou o tkprof para verificar o plano de execução da consulta) e analise ou calcule as estatísticas nas tabelas em questão, se isso não tiver sido feito recentemente. A reconstrução (ou eliminação / recriação) de índices também pode ajudar.

3.1) A instrução SQL é MERGE? avalie os dados retornados pela cláusula USING para garantir que não haja valores duplicados na associação. Modifique a instrução merge para incluir uma cláusula where determinística

3.2) Esta é uma instrução UPDATE através de uma visualização? Nesse caso, tente preencher o resultado da exibição em uma tabela e tente atualizar a tabela diretamente.

3.3) Existe um gatilho na mesa? Tente desativá-lo para ver se ainda falha.

3.4) A declaração contém uma visão não mesclável em uma 'Subconsulta IN'? Isso pode resultar no retorno de linhas duplicadas se a consulta tiver uma cláusula "FOR UPDATE". Veja Bug 2681037

3.5) A tabela possui colunas não utilizadas? Largar estes pode impedir o erro.

4) Se a modificação do SQL não resolver o erro, o problema pode estar na 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 verificar se há alguma corrupção na tabela ou em seus índices. 4.2) Verifique e elimine quaisquer LINHAS CHAINED ou migradas na tabela. Existem maneiras de minimizar isso, como a configuração correta do PCTFREE. Use a Nota 122020.1 - Encadeamento e migração de linhas 4.3) Se a tabela for adicionalmente organizada por índices, consulte: Nota 102932.1 - Monitorando linhas encadeadas em IOTs

Tagar
fonte
5

O erro ocorreu hoje em um 12c e nenhuma das respostas existentes se encaixou (sem duplicatas, sem expressões não determinísticas na cláusula WHERE). Meu caso foi relacionado a essa outra causa possível do erro, de acordo com o texto da mensagem da Oracle (ênfase abaixo):

ORA-30926: não é possível obter um conjunto estável de linhas nas tabelas de origem
Causa: Não foi possível obter um conjunto estável de linhas devido a uma grande atividade dml ou a uma cláusula where não determinística.

A mesclagem fazia parte de um lote maior e foi executada em um banco de dados ativo com muitos usuários simultâneos. Não havia necessidade de alterar a declaração. Acabei de confirmar a transação antes da mesclagem, executei a mesclagem separadamente e confirmei novamente. Portanto, a solução foi encontrada na ação sugerida da mensagem:

Ação: Remova todas as cláusulas where não determinísticas e emita novamente o dml .

Cee McSharpface
fonte
Eu estava recebendo essa mensagem de erro fazendo uma importação do DataPump via rede (usando o NETWORK_LINKparâmetro que se conecta diretamente ao banco de dados de origem) durante o estágio de coleta de estatísticas, e sua nota destacada provavelmente explica isso. Felizmente, apenas as estatísticas foram afetadas.
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.

Este erro ocorreu para mim devido a registros duplicados (16K)

Eu tentei com único que funcionou .

mas novamente quando tentei mesclar sem o mesmo problema ocorreu Segunda vez que era devido a confirmação

após a mesclagem se a confirmação não for feita, o mesmo erro será mostrado.

Sem exclusivo, o Query funcionará se a confirmação for dada após cada operação de mesclagem.

v8-E
fonte
-1

Um esclarecimento adicional sobre o uso do DISTINCT para resolver o erro ORA-30926 no caso geral:

Você precisa garantir que o conjunto de dados especificado pela cláusula USING () não tenha valores duplicados das colunas de junção , ou seja, as colunas da cláusula ON () .

No exemplo do OP, em que a cláusula USING seleciona apenas uma chave, foi suficiente adicionar DISTINCT à cláusula USING. No entanto, no caso geral, a cláusula USING pode selecionar uma combinação de colunas-chave para combinar e atribuir colunas a serem usadas na cláusula UPDATE ... SET. Portanto, no caso geral, adicionar DISTINCT à cláusula USING ainda permitirá linhas de atualização diferentes para as mesmas chaves; nesse caso, você ainda receberá o erro ORA-30926.

Esta é uma elaboração da resposta de DCookie e do ponto 3.1 da resposta de Tagar, que pela minha experiência pode não ser imediatamente óbvio.

Durban_legend
fonte