web-dev-qa-db-fra.com

ORA-30926: impossible d'obtenir un ensemble stable de lignes dans les tables source lors de la fusion de tables

J'ai cette déclaration de fusion:

MERGE INTO TB_DP_REGIAO B
USING TMP_DP_REGIAO P
ON (P.DS_PROTHEUS_CODE = B.DS_PROTHEUS_CODE)
WHEN MATCHED THEN UPDATE SET B.DS_PLANNING_CODE = CASE WHEN B.DT_LOAD < P.DT_LOAD THEN P.DS_PLANNING_CODE ELSE B.DS_PLANNING_CODE END,
                             B.DT_LOAD = CASE WHEN B.DT_LOAD < P.DT_LOAD THEN P.DT_LOAD ELSE B.DT_LOAD END
WHEN NOT MATCHED THEN INSERT(B.DS_PROTHEUS_CODE, B.DS_PLANNING_CODE, B.DT_LOAD) VALUES(P.DS_PROTHEUS_CODE, P.DS_PLANNING_CODE, P.DT_LOAD);

Cela me renvoie cette erreur:

Error starting at line 1 in command:
MERGE INTO TB_DP_REGIAO B
USING TMP_DP_REGIAO P
ON (P.DS_PROTHEUS_CODE = B.DS_PROTHEUS_CODE)
WHEN MATCHED THEN UPDATE SET B.DS_PLANNING_CODE = CASE WHEN B.DT_LOAD < P.DT_LOAD THEN P.DS_PLANNING_CODE ELSE B.DS_PLANNING_CODE END,
                             B.DT_LOAD = CASE WHEN B.DT_LOAD < P.DT_LOAD THEN P.DT_LOAD ELSE B.DT_LOAD END
WHEN NOT MATCHED THEN INSERT(B.DS_PROTHEUS_CODE, B.DS_PLANNING_CODE, B.DT_LOAD) VALUES(P.DS_PROTHEUS_CODE, P.DS_PLANNING_CODE, P.DT_LOAD)
Error report:
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.

Lorsque la table cible est vide, cela fonctionne. Si je l'exécute lorsque le P.DT_LOAD est identique à B.DT_LOAD, cela fonctionne. Lorsque je l'exécute le lendemain, lorsque le P.DT_LOAD a un jour d'avance, j'obtiens cette erreur.

Quelqu'un peut m'aider à ce sujet?

Merci d'avance!

4
Lucas Rezende

C'est un cas un peu délicat. La raison principale est que vous semblez avoir des doublons dans la colonne TMP_DP_REGIAO.DS_PROTHEUS_CODE et que MERGE tente de mettre à jour la même ligne de la table de destination plusieurs fois. Mais si les nouvelles valeurs et les anciennes valeurs dans les colonnes mises à jour sont identiques, Oracle peut ignorer ce problème de doublons:

SQL> select * from t;

      CODE TEXT                                                                 
---------- ----------                                                           
         1 test                                                                 

SQL> merge into t using (
  2   select 1 code,'test' text from dual union all
  3   select 1 code,'test' text from dual
  4  ) s
  5  on (t.code = s.code)
  6  when matched then
  7    update set t.text = s.text
  8  /

2 rows merged 

Mais si les anciennes et les nouvelles valeurs sont différentes, Oracle déclenche l'exception que vous obtenez:

SQL> merge into t using (
  2   select 1 code,'a' text from dual union all
  3   select 1 code,'a' text from dual
  4  ) s
  5  on (t.code = s.code)
  6  when matched then
  7    update set t.text = s.text
  8  /
merge into t using (
           *
error in line 1:
ORA-30926: unable to get a stable set of rows in the source tables 
6
Dmitry Nikiforov

Une autre raison de ce problème pourrait également être les conditions spécifiées dans la clause ON. Cette erreur se produit lorsqu'il existe un mappage de 1 à plusieurs entre vos lignes de destination et vos lignes source, ce qui peut être dû à deux raisons.

1) there are duplicate rows in source table.
2) there are unique rows in source table, but ON clause conditions are pointing to multiple rows in the source table.

Dans le second cas, les conditions de la clause ON doivent être modifiées pour obtenir un mappage de 1 à 1 ou de plusieurs à un dans la table source et source.

1
Pawan Rawat