sql >> Base de Datos >  >> RDS >> Oracle

Uso de sentencias WITH y UPDATE en la misma consulta SQL

Puede usar una cláusula with en una actualización; solo tienes que hacerlo en el lugar correcto:

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

Sin embargo, probablemente desee actualizar solo las filas que existen en la subconsulta temporal, por lo que necesitaría una cláusula where adicional:

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

Alternativamente, use una instrucción 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;

nótese bien tiene que unirse a la tabla real en la consulta de origen de la declaración de combinación porque está tratando de actualizar la columna a la que se está uniendo, lo que no puede hacer en una declaración de combinación; por lo tanto, he cambiado la combinación de combinación a unirse a mytable.rowid.

Tendría que probar ambas declaraciones para ver cuál funciona mejor con sus datos.