代码之家  ›  专栏  ›  技术社区  ›  chrismarx

在Oracle中更新多个嵌套表中的多个记录

  •  6
  • chrismarx  · 技术社区  · 14 年前

    我有一个Oracle表,其中一些列中有嵌套表。现在,我需要能够更新每个嵌套表、主表的每个记录中的所有记录。这是如何完成的?我尝试过的任何一种方法都会出错,或者是无法对该视图执行更新,或者是单行子查询返回多行。

    下面是一个例子。我可以运行这样的更新:

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

    但在本例中,table子句是从一行中对单个嵌套表执行的。如果您不希望只需要等于2的entity.uidn,如何执行这样的更新?

    谢谢!

    1 回复  |  直到 9 年前
        1
  •  10
  •   APC    14 年前

    也许避免在数据库中使用嵌套表的最好原因是,它们很难使用,而且语法没有文档化,很难摸索。

    继续前进!

    这是一个带有嵌套表的表。

    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 ,通过嵌套的_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;
                                        ^^^^^^^^^^^^^^^^
    
    推荐文章