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

zaktualizować wiele rekordów w wielu zagnieżdżonych tabelach w Oracle

Być może najlepszym powodem unikania tabel zagnieżdżonych w bazie danych jest to, że ciężko się z nimi pracuje, a składnia jest niedokumentowana i trudna do obsadzenia.

Ruszamy!

Oto tabela z tabelą zagnieżdżoną.

SQL> select f.force_name, t.id, t.name
  2  from transformer_forces f, table(f.force_members) t
  3  /

FORCE_NAME         ID NAME
---------- ---------- --------------------
Autobot             0 Metroplex
Autobot             0 Optimus Prime
Autobot             0 Rodimus
Decepticon          0 Galvatron
Decepticon          0 Megatron
Decepticon          0 Starscream
Dinobot             0 Grimlock
Dinobot             0 Swoop
Dinobot             0 Snarl

9 rows selected.

SQL>

Jak widać, dla każdego elementu w zagnieżdżonej tabeli atrybut ID jest ustawiony na zero we wszystkich przypadkach. To, co chcielibyśmy zrobić, to zaktualizować je wszystkie. Ale niestety!

SQL> update table
  2   ( select force_members from transformer_forces ) t
  3  set t.id = rownum
  4  /
 ( select force_members from transformer_forces ) t
   *
ERROR at line 2:
ORA-01427: single-row subquery returns more than one row


SQL> 

Możliwe jest zaktualizowanie wszystkich elementów w zagnieżdżonej tabeli dla pojedynczego wiersza w tabeli trzymającej:

SQL> update table
  2       ( select force_members from transformer_forces
  3         where force_name = 'Autobot') t
  4      set t.id = rownum
  5  /

3 rows updated.

SQL>

Ale jedyny sposób na zrobienie tego tego dla całej tabeli jest pętla PL/SQL. Fuj!

Istnieje alternatywa:użyj tabeli zagnieżdżonej Lokalizator , za pomocą wskazówki NESTED_TABLE_GET_REFS. Jest to szczególnie niejasna rzecz (nie znajduje się w główna lista podpowiedzi ) ale to załatwia sprawę:

SQL> update /*+ NESTED_TABLE_GET_REFS */ force_members_nt
  2  set id = rownum
  3  /

9 rows updated.

SQL> select f.force_name, t.id, t.name
  2  from transformer_forces f, table(f.force_members) t
  3  /

FORCE_NAME         ID NAME
---------- ---------- --------------------
Autobot             1 Metroplex
Autobot             2 Optimus Prime
Autobot             3 Rodimus
Decepticon          4 Galvatron
Decepticon          5 Megatron
Decepticon          6 Starscream
Dinobot             7 Grimlock
Dinobot             8 Swoop
Dinobot             9 Snarl

9 rows selected.

SQL>

Ta wskazówka pozwala nam całkowicie ominąć tabelę przetrzymywania i pracować z faktycznie zagnieżdżoną tabelą. Oznacza to, że obiekt określony w klauzuli przechowywania tabeli zagnieżdżonej:

create table transformer_forces (
    force_name varchar2(10)
    , force_members transformers_nt)
nested table force_members store as force_members_nt return as value;
                                    ^^^^^^^^^^^^^^^^



  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 można uruchomić skrypt SQLPLUS na pliku zakodowanym jako UTF-8 z BOM?

  2. Wydajne sprzężenie ze skorelowanym podzapytaniem

  3. Wstawianie wielu wierszy do Oracle

  4. Konwersja ciągu ze skróconą strefą czasową na znacznik czasu

  5. Jak uzyskać typ danych kolumny w Oracle z PL-SQL z niskimi uprawnieniami?