Actualice los resultados de una instrucción SELECT

Oracle le permite actualizar los resultados de una instrucción SELECT.

UPDATE (<SELECT Statement>) SET <column_name> = <value> WHERE <column_name> <condition> <value>; 

Supongo que esto podría usarse para actualizar columnas en una tabla en function del valor de una fila coincidente en otra tabla.

¿Cómo se llama esta característica? ¿Se puede usar de manera eficiente para grandes actualizaciones? ¿Funciona cuando SELECT se une a varias tablas y, de ser así, cómo?

No he visto un nombre formal para esto. La reference de Oracle SQL simplemente se refiere a la actualización de una subconsulta. Tiendo a pensar en ello como una forma de "ver la actualización", con la subconsulta en la vista en línea.

Sí, funciona cuando se unen varias tablas, pero está sujeto a la actualización de las reglas de visualización. Esto significa que solo se puede actualizar una de las tablas base de la vista, y esta tabla debe conservarse "key" en la vista: es decir, sus filas solo deberían poder aparecer una vez en la vista. Esto requiere que cualquier otra tabla en la vista (subconsulta) se haga reference a través de restricciones de key externa en la tabla que se actualizará.

Algunos ejemplos pueden ayudar. Utilizando las tablas estándar EMP y DEP de Oracle, con EMP.EMPNO definido como la key principal de EMP, y EMP.DEPTNO definido como una key externa para DEPT.DEPTNO, esta actualización está permitida:

 update (select emp.empno, emp.ename, emp.sal, dept.dname from emp join dept on dept.deptno = emp.deptno ) set sal = sal+100; 

Pero esto no es:

 -- DEPT is not "key-preserved" - same DEPT row may appear -- several times in view update (select emp.ename, emp.sal, dept.deptno, dept.dname from emp join dept on dept.deptno = emp.deptno ) set dname = upper(dname); 

En cuanto al performance: el optimizador identificará (debe) la tabla base que se actualizará durante el análisis sintáctico, y las uniones a otra tabla serán ignoradas ya que no tienen ninguna relación con la actualización que se realizará, ya que este resultado AUTOTRACE muestra:

 SQL> update (select emp.ename, emp.sal, dept.dname 2 from emp join dept on dept.deptno = emp.deptno 3 ) 4 set sal = sal-1; 33 rows updated. Execution Plan ---------------------------------------------------------- Plan hash value: 1507993178 ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------ | 0 | UPDATE STATEMENT | | 33 | 495 | 3 (0)| 00:00:01 | | 1 | UPDATE | EMP | | | | | | 2 | NESTED LOOPS | | 33 | 495 | 3 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL| EMP | 33 | 396 | 3 (0)| 00:00:01 | |* 4 | INDEX UNIQUE SCAN| SYS_C0010666 | 1 | 3 | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------ Pnetworkingicate Information (identified by operation id): --------------------------------------------------- 4 - access("EMP"."DEPTNO"="DEPT"."DEPTNO") 

(Tenga en count que nunca se accede a la tabla DEPT aunque DEPT.DNAME aparezca en la subconsulta).

El formulario que menciona no tiene un nombre específico AFAIK. Simplemente actualizando el resultado de una statement seleccionada.

Hay otro formulario llamado Actualización correlacionada (con actualización de una sola hoja o de varias columnas)

 UPDATE TABLE(<SELECT STATEMENT>) <alias> SET <column_name> = ( SELECT <column_name> FROM <table_name> <alias> WHERE <alias.table_name> <condition> <alias.table_name> ); 

La forma multicolumna

 ... SET (<column_name_list>) = ( SELECT <column_name_list> ... 

También hay un retorno de valores llamado Update with returning clause

Y algunos detalles para las actualizaciones con tablas anidadas. Lo mejor es comprobar al less estas dos páginas

Oracle® Database SQL Language Reference SELECCIONE

Oracle® Database SQL Language Reference ACTUALIZACIÓN

Gracias por los comentarios, pensé que esto era estándar Sql … 🙁

Para Oracle puede escribir una actualización en una tabla donde recupera información con una combinación como:

 UPDATE ( SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t2.t1id = t1.ID ) SET t1.col1 = t2.col2 

Para el server Sql, es:

 UPDATE t1 SET col1 = t2.col2 FROM table1 t1 LEFT JOIN table2 t2 on t2.t1id = t1.id 

Si alguien sabe una manera de hacer esto que funcione en Oracle, SQL Server y MySql me interesaría.