2010-07-15 9 views
6

У меня есть таблица оракула с вложенными таблицами в некоторых столбцах. Теперь мне нужно обновить все записи в каждой вложенной таблице в каждой из записей основной таблицы. Как это достигается? Любой из способов, которые я пробовал, я получаю ошибки в том, что вы не можете выполнять обновления в этом представлении, или подзапрос одной строки возвращает более одной строки.обновление нескольких записей в нескольких вложенных таблицах в oracle

вот пример из иллюстрации. Я могу запустить обновление так:

UPDATE TABLE(select entity.name 
       from entity 
       where entity.uidn = 2) 
    SET last = 'Decepticon', 
    change_date = SYSDATE, 
    change_user = USER 
    WHERE first = 'Galvatron'; 

, но в этом случае предложение таблицы выполняется на одной вложенной таблице из одной строки. Как бы такое обновление было выполнено, если вы не хотели, чтобы только entity.uidn равнялся 2?

спасибо!

ответ

10

Возможно, лучшая причина для избежания вложенных таблиц в базе данных состоит в том, что с ними трудно работать, а синтаксис недооценен и трудно перегружен.

Продолжение дальше!

Вот таблица со вложенной таблицей.

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

Ничего себе, спасибо! Какое замечательное подробное изложение, я надеюсь, что это поможет другим с той же проблемой. Я нашел работу с вложенными таблицами более интуитивной в некоторых случаях (особенно при использовании объектно-ориентированного java-приложения), но немного громоздкой в ​​других - – chrismarx

Смежные вопросы