web-dev-qa-db-fra.com

Oracle Update relevé avec clause prend pour toujours

J'essaie d'écrire une déclaration de mise à jour, qui utilise le résultat d'une série d'agrégations de with énoncé ci-dessous.

update final_table
set(destination_col1,destination_col2)=
(
select c4,c5
from
(
  with temp_table1(c1,c2,c3) as
  select c7,c7,c9 from source_table,

  temp_table2(c4,c5,c6) as
  select "some aggregation on c1,c2",c3 from temp_table

  select * from temp_table2
)
where c6= final_table.primary_key
);

Cela fonctionne pour toujours.

Alors que, lorsque j'essaie de briser la même chose en 2 requêtes, cela fonctionne.

  1. Création d'une table à l'aide de la requête interne.
  2. Utilisez la table ci-dessus pour mettre à jour comme,

    update final_table
        set(destination_col1,destination_col2)=
        (select c4,c5 from step1_table where c6=final_table.primary_key)
    

Comme suggéré ici , j'ai essayé de vérifier s'il y a des serrures. Mais je n'en ai pas.

Est-ce que je abuse de l'with statement? Pourquoi exactement mes attentes ne sont pas remplies?

1
Kannan Ramamoorthy

Est-ce que je abuse de la déclaration avec la déclaration?

Non, vous abusez la déclaration de mise à jour. Avec une déclaration de mise à jour, la sous-requête corrélée est exécutée pour chaque ligne de Final_Table.

La mise à jour des valeurs d'une autre table doit être typiquement faite avec fusion.

Exemple:

merge into final_table using
(
select c4,c5,c6
from
(
  with temp_table1(c1,c2,c3) as
  select c7,c7,c9 from source_table,

  temp_table2(c4,c5,c6) as
  select "some aggregation on c1,c2",c3 from temp_table

  select * from temp_table2
)
) inner
on inner.c6 = final_table.primary_key
when matched then update set final_table.destination_col1 = inner.c4, 
                             final_table.destination_col2 = inner.c5;
2
Balazs Papp