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