Oracle
 sql >> база данни >  >> RDS >> Oracle

Актуализирайте резултатите от оператор SELECT

Не съм виждал официално име за това. Oracle SQL Reference просто се отнася до актуализиране на подзаявка. Склонен съм да мисля за това като за форма на „актуализиране на изглед“, като подзаявката е в изглед на линия.

Да, работи, когато няколко таблици са обединени, но при спазване на правилата за актуализиране на изгледа. Това означава, че само една от базовите таблици на изгледа може да бъде актуализирана и тази таблица трябва да бъде „запазена с ключ“ в изгледа:т.е. нейните редове трябва да могат да се появяват само веднъж в изгледа. Това изисква всички други таблици в изгледа (подзаявка) да бъдат препратени чрез ограничения на външен ключ на таблицата, която трябва да се актуализира.

Някои примери могат да помогнат. Използвайки стандартните EMP и DEPT таблици на Oracle, като 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 се появява в подзаявката).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Папката на продукта за инсталиране на Oracle и папката за диагностика на различно място

  2. Oracle SQL заявка:Извличане на най-новите стойности за група въз основа на времето

  3. ORA-30076:невалидно поле за извлечение за източник на извлечение

  4. Oracle преобразува редове в колони

  5. как да добавите повече от 1000 стойности с клауза NOT IN