Peut-être que la meilleure raison d'éviter les tables imbriquées dans une base de données est qu'elles sont difficiles à utiliser et que la syntaxe est sous-documentée et difficile à comprendre.
Passons à autre chose !
Voici un tableau avec un tableau imbriqué.
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>
Comme vous pouvez le voir, chaque élément de la table imbriquée, l'attribut ID est défini sur zéro dans tous les cas. Ce que nous aimerions faire, c'est les mettre à jour tous. Mais, hélas !
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>
Il est possible de mettre à jour tous les éléments d'une table imbriquée pour une seule ligne de la table d'exploitation :
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>
Mais la seule façon de faire ça pour toute la table est une boucle PL/SQL. Beurk !
Il existe une alternative :utiliser une table imbriquée Localisateur , via l'indicateur NESTED_TABLE_GET_REFS. C'est une chose particulièrement obscure (ce n'est pas dans le liste principale des astuces ) mais ça fait l'affaire :
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>
Cette astuce nous permet de contourner complètement la table de maintien et de travailler avec la table imbriquée réelle. C'est-à-dire l'objet spécifié dans la clause Nested Table storage :
create table transformer_forces (
force_name varchar2(10)
, force_members transformers_nt)
nested table force_members store as force_members_nt return as value;
^^^^^^^^^^^^^^^^