sql >> Database >  >> RDS >> Oracle

update meerdere records in meerdere geneste tabellen in oracle

Misschien is de beste reden om geneste tabellen in een database te vermijden, dat ze moeilijk zijn om mee te werken, en de syntaxis is ondergedocumenteerd en moeilijk te kraken.

Verder gaan!

Hier is een tabel met een geneste 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>

Zoals u kunt zien, wordt voor elk element in de geneste tabel het ID-attribuut in alle gevallen op nul gezet. Wat we zouden willen doen, is ze allemaal bijwerken. Maar helaas!

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> 

Het is mogelijk om alle elementen in een geneste tabel bij te werken voor een enkele rij in de holdingtabel:

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>

Maar de enige manier om dat te doen voor de hele tabel is een PL/SQL-lus. Bah!

Er is een alternatief:gebruik een geneste tabel Zoekfunctie , via de NESTED_TABLE_GET_REFS-hint. Dit is een bijzonder obscuur iets (het staat niet in de hoofdlijst met hints ) maar het werkt wel:

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>

Met deze hint kunnen we de vasthoudtabel helemaal omzeilen en met de daadwerkelijke geneste tabel werken. Dat wil zeggen, het object gespecificeerd in de Nested Table-opslagclausule:

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. Waarschuwing:mysql_query():Toegang geweigerd voor gebruiker 'admin'@'localhost' (met wachtwoord:NEE)

  2. Wat zijn de 10 beste functies van Microsoft Access?

  3. Oracle SQL:het gedrag van SYS_GUID() begrijpen wanneer aanwezig in een inline-weergave?

  4. Voorwaardelijke parameters voor het maken van query's