Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Usando instruções WITH e UPDATE na mesma consulta SQL


Você pode usar uma cláusula with em uma atualização; você só tem que fazer isso no lugar certo:
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);

No entanto, você provavelmente deseja atualizar apenas as linhas que existem na subconsulta temporária, portanto, você precisaria de uma 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);

Como alternativa, use uma instrução 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.B. você precisa ingressar na tabela real na consulta de origem da instrução de mesclagem porque está tentando atualizar a coluna que está sendo unida, o que não pode ser feito em uma instrução de mesclagem - portanto, mudei a junção de mesclagem para junte-se em mytable.rowid.

Você teria que testar as duas declarações para ver qual delas tem melhor desempenho em seus dados.