Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Zaktualizuj wyniki instrukcji SELECT

Nie widziałem na to oficjalnej nazwy. Oracle SQL Reference odnosi się tylko do aktualizacji podzapytania. Myślę o tym jako o formie „aktualizacji widoku”, przy czym podzapytanie jest w widoku wbudowanym.

Tak, działa, gdy kilka tabel jest połączonych, ale podlega zasadom aktualizacji widoków. Oznacza to, że tylko jedna z tabel podstawowych widoku może zostać zaktualizowana, a ta tabela musi być „zachowana klucza” w widoku, tj. jej wiersze powinny być widoczne tylko raz w widoku. Wymaga to, aby wszelkie inne tabele w widoku (podzapytanie) były przywoływane przez ograniczenia klucza obcego w tabeli, która ma zostać zaktualizowana.

Kilka przykładów może pomóc. Ta aktualizacja jest dozwolona przy użyciu standardowych tabel Oracle EMP i DEPT, przy czym EMP.EMPNO jest zdefiniowany jako klucz podstawowy EMP, a EMP.DEPTNO jest zdefiniowany jako klucz obcy 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;

Ale to nie jest:

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

Jeśli chodzi o wydajność:optymalizator (musi) zidentyfikować tabelę bazową, która ma zostać zaktualizowana podczas parsowania, a połączenia z inną tabelą zostaną zignorowane, ponieważ nie mają żadnego wpływu na aktualizację, która ma zostać wykonana - jak pokazuje to wyjście AUTOTRACE:

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

(Zauważ, że tabela DEPT nigdy nie jest dostępna, mimo że DEPT.DNAME pojawia się w podzapytaniu).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy EF6 może generować moje obiekty modelu z kursora ref zwróconego przez procedurę składowaną Oracle?

  2. Jak wstawić rekordy do zmiennych z cte w oracle?

  3. PreparedStatement pomyślnie wykonany w Oracle, ale zgłaszający wyjątek w Microsoft SQL

  4. Jaka jest różnica między funkcjami RANK() i DENSE_RANK() w Oracle?

  5. Tworzenie formularza w APEX w celu ustawienia zmiennych w zapytaniu dla interaktywnego raportu