Oracle
 sql >> Database >  >> RDS >> Oracle

Utilizzo delle istruzioni WITH e UPDATE nella stessa query SQL

È possibile utilizzare una clausola with in un aggiornamento; devi solo farlo nel posto giusto:

UPDATE mytable
   SET name = (WITH temp AS((SELECT 'abcd' AS oldvalue, 'defg' AS newvalue FROM dual) UNION
                            (SELECT .....) --About 300 lines of this, copied from Excel and then formatted into the SELECT statement
                           )
               SELECT newvalue
               FROM   temp
               WHERE  mytable.name = temp.oldvalue);

Tuttavia, probabilmente vorrai aggiornare solo le righe che esistono nella subquery temporanea, quindi avresti bisogno di una clausola where aggiuntiva:

UPDATE mytable
   SET name = (WITH temp AS((SELECT 'abcd' AS oldvalue, 'defg' AS newvalue FROM dual) UNION
                            (SELECT .....) --About 300 lines of this, copied from Excel and then formatted into the SELECT statement
                           )
               SELECT newvalue
               FROM   temp
               WHERE  mytable.name = temp.oldvalue)
WHERE  EXISTS (WITH temp AS((SELECT 'abcd' AS oldvalue, 'defg' AS newvalue FROM dual) UNION
                            (SELECT .....) --About 300 lines of this, copied from Excel and then formatted into the SELECT statement
                           )
               SELECT NULL
               FROM   temp
               WHERE  mytable.name = temp.oldvalue);

In alternativa, usa un'istruzione MERGE:

merge into mytable tgt
  using (WITH temp AS((SELECT 'abcd' AS oldvalue, 'defg' AS newvalue FROM dual) UNION
                      (SELECT .....) --About 300 lines of this, copied from Excel and then formatted into the SELECT statement
                     )
         SELECT mytable.rowid r_id,
                temp.newvalue
         FROM   temp
         inner  join mytable on mytable.name = temp.oldvalue) src
    on (tgt.rowid = src.r_id)
when matched then
update set tgt.name = src.newvalue;

NB devi unirti alla tabella effettiva nella query di origine dell'istruzione di unione perché stai cercando di aggiornare la colonna su cui viene unito, cosa che non puoi fare in una dichiarazione di unione, quindi ho cambiato l'unione di unione in unisciti a mytable.rowid.

Dovresti testare entrambe le affermazioni per vedere quale è più performante sui tuoi dati.