sql >> Database teknologi >  >> RDS >> Oracle

opdater flere poster i flere indlejrede tabeller i Oracle

Den bedste grund til at undgå indlejrede tabeller i en database er måske, at de er svære at arbejde med, og syntaksen er underdokumenteret og svær at grok.

Går videre!

Her er en tabel med en indlejret tabel.

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>

Som du kan se, er ID-attributten for hvert element i den indlejrede tabel sat til nul i alle tilfælde. Det, vi gerne vil gøre, er at opdatere dem alle. Men ak!

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> 

Det er muligt at opdatere alle elementerne på en indlejret tabel for en enkelt række i holdetabellen:

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>

Men den eneste måde at gøre det på for hele bordet er en PL/SQL-løkke. Yuck!

Der er et alternativ:brug en indlejret tabel Finder , via NESTED_TABLE_GET_REFS tippet. Dette er en særlig obskur ting (det er ikke i hovedliste med tip ), men det gør tricket:

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>

Dette tip giver os mulighed for at omgå holdetabellen helt og arbejde med den faktiske indlejrede tabel. Det vil sige det objekt, der er angivet i lagringssætningen Nested Table:

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. com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException:Kan ikke kalde rollback, når autocommit=true

  2. Kan SQL Server Express LocalDB tilsluttes eksternt?

  3. Mysql Ugyldigt datetime-format:1292 Forkert datetime-værdi ved oprettelse af nogle dummy-data til test

  4. Hvordan grupperes efter dato, idet der tages højde for tidszoner og sommertid?