私はこれの正式な名前を見たことがありません。 OracleSQLリファレンス サブクエリの更新を指すだけです。私はそれを「ビューの更新」の一形態と考える傾向があり、サブクエリはインラインビューにあります。
はい、それはいくつかのテーブルが結合されているときに機能しますが、ビューの更新のルールに従います。つまり、更新できるのはビューのベーステーブルの1つだけであり、このテーブルはビューで「キー保存」する必要があります。つまり、その行はビューに1回だけ表示できる必要があります。これには、ビュー内の他のテーブル(サブクエリ)が、更新されるテーブルの外部キー制約を介して参照される必要があります。
いくつかの例が役立つ場合があります。 EMP.EMPNOがEMPの主キーとして定義され、EMP.DEPTNOがDEPT.DEPTNOの外部キーとして定義されている、標準のOracle EMPおよびDEPTテーブルを使用すると、この更新が許可されます。
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.DNAMEが表示されていても、テーブルDEPTにアクセスすることはありません。