sql >> Database >  >> RDS >> Oracle

Werk de resultaten van een SELECT-instructie bij

Ik heb hier geen officiële naam voor gezien. De Oracle SQL-referentie verwijst alleen naar het bijwerken van een subquery. Ik heb de neiging om het te zien als een vorm van "view-update", waarbij de subquery in in-line view is.

Ja, het werkt wanneer een aantal tabellen zijn samengevoegd, maar onderhevig aan de regels voor het bijwerken van de weergave. Dit betekent dat slechts één van de basistabellen van de weergave kan worden bijgewerkt, en deze tabel moet in de weergave "met een sleutel behouden" zijn:dat wil zeggen dat de rijen ervan slechts één keer in de weergave mogen voorkomen. Dit vereist dat naar andere tabellen in de weergave (subquery) wordt verwezen via externe-sleutelbeperkingen in de tabel die moet worden bijgewerkt.

Enkele voorbeelden kunnen helpen. Als u de standaard Oracle EMP- en DEPT-tabellen gebruikt, waarbij EMP.EMPNO is gedefinieerd als de primaire sleutel van EMP en EMP.DEPTNO is gedefinieerd als een externe sleutel voor DEPT.DEPTNO, is deze update toegestaan:

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

Maar dit is niet:

-- 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);

Wat de prestaties betreft:de optimizer (moet) de basistabel identificeren die moet worden bijgewerkt tijdens het parseren, en joins met andere tabellen worden genegeerd omdat ze geen invloed hebben op de uit te voeren update - zoals deze AUTOTRACE-uitvoer laat zien:

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")

(Merk op dat tabel DEPT nooit wordt geopend, ook al verschijnt DEPT.DNAME in de subquery).



  1. automatisch mysql-veld bijwerken op basis van waarde van ander veld

  2. Hoe voeg ik een foto toe aan de mysql-database met behulp van php?

  3. Hoe willekeurige rijen uit de database herhalen?

  4. Waarom krijg ik TableRegistry niet gevonden in CakePhP 3.0?