Возможно, лучшая причина для избежания вложенных таблиц в базе данных состоит в том, что с ними трудно работать, а синтаксис недооценен и трудно перегружен.
Продолжение дальше!
Вот таблица со вложенной таблицей.
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>
Как вы можете видеть, каждый элемент во вложенной таблице атрибут ID устанавливается равным нулю во всех случаях. Нам бы хотелось обновить их все. Но увы!
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>
можно обновить все элементы на вложенную таблицу для одной строки в таблице удерживающей:
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>
Но единственным способом сделать что для всей таблицы является Цикл PL/SQL. Тьфу!
Существует альтернатива: use a Nested Table Locator, с помощью подсказки NESTED_TABLE_GET_REFS. Это особенно неясная вещь (это не в main list of hints), но это делает трюк:
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>
Этой подсказка позволяет обойти таблицу удерживающей вообще и работать с фактической вложенной таблицей. То есть объект, указанный в предложении хранения вложенных таблиц:
create table transformer_forces (
force_name varchar2(10)
, force_members transformers_nt)
nested table force_members store as force_members_nt return as value;
^^^^^^^^^^^^^^^^
Ничего себе, спасибо! Какое замечательное подробное изложение, я надеюсь, что это поможет другим с той же проблемой. Я нашел работу с вложенными таблицами более интуитивной в некоторых случаях (особенно при использовании объектно-ориентированного java-приложения), но немного громоздкой в других - – chrismarx