Я не видел официального названия для этого. Oracle SQL Reference просто ссылается на обновление подзапроса. Я склонен думать об этом как о форме «обновления представления», когда подзапрос находится во встроенном представлении.
Да, работает, когда объединено несколько таблиц, но при условии обновления правил просмотра. Это означает, что только одна из базовых таблиц представления может быть обновлена, и эта таблица должна быть «сохранена на ключе» в представлении: то есть ее строки должны появляться в представлении только один раз. Это требует, чтобы на любые другие таблицы в представлении (подзапросе) ссылались через ограничения внешнего ключа для обновляемой таблицы.
Некоторые примеры могут помочь. Используя стандартные таблицы Oracle EMP и DEPT, где EMP.EMPNO определяется как первичный ключ EMP, а EMP.DEPTNO определяется как внешний ключ для DEPT.DEPTNO, тогда это обновление разрешено:
update (select emp.empno, emp.ename, emp.sal, dept.dname
from emp join dept on dept.deptno = emp.deptno
)
set sal = sal+100;
Но это не так:
-- 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);
Что касается производительности: оптимизатор будет (должен) идентифицировать базовую таблицу, подлежащую обновлению во время синтаксического анализа, и присоединения к другой таблице будут игнорироваться, поскольку они не имеют никакого отношения к выполнению обновления - как показывает этот выход AUTOTRACE :
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 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
(Обратите внимание, что таблица DEPT никогда не доступна, даже если в подзапросе присутствует DEPT.DNAME).