2010-07-15 70 views
6

我在某些列中有一个带有嵌套表的oracle表。现在,我需要能够在主表的每个记录中更新每个嵌套表中的所有记录。这是如何完成的?我尝试过的任何方式都会导致无法在该视图上执行更新或者单行子查询返回多行的错误。更新oracle中多个嵌套表中的多条记录

这里是一个例子来说明。我可以像这样运行一个更新:

​​

但是在这种情况下,table子句从一行中的单个嵌套表上执行。如果你不想只有等于2的entity.uidn,那么如何执行这样的更新?

谢谢!

回答

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 2010-07-15 19:53:27