更新oracle中多个嵌套表中的多条记录

发布于 2024-09-10 05:05:07 字数 471 浏览 2 评论 0原文

我有一个 oracle 表,其中一些列中有嵌套表。现在,我需要能够更新每个嵌套表中的所有记录以及主表的每个记录中的所有记录。这是如何实现的?我尝试过的任何方法都会收到有关无法对该视图执行更新或单行子查询返回多行的错误。

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

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

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

谢谢!

I have an oracle table with nested tables in some of the columns. Now, I need to be able to update all the records in each nested table, in each of the records of the main table. How is this accomplished? Any of the ways that I've tried, I get errors about either not be able to perform updates on that view, or single row subquery returns more than one row.

here's an example from to illustrate. I can run an update like this:

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

but in this case, the table clause is being executed on a single nested table from a single row. How would an update like this be performed if you didn't want just the entity.uidn which equalled 2?

thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还在原地等你 2024-09-17 05:05:07

也许避免在数据库中使用嵌套表的最好原因是它们很难使用,而且语法记录不足且难以理解。

继续前进!

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

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 循环。哎呀!

还有一种替代方法:使用嵌套表定位器< /a>,通过 NESTED_TABLE_GET_REFS 提示。这是一件特别晦涩的事情(它不在 主要提示列表),但它确实有用:

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>

此提示允许我们完全绕过保持表并使用实际的嵌套表。即Nested Table存储子句中指定的对象:

create table transformer_forces (
    force_name varchar2(10)
    , force_members transformers_nt)
nested table force_members store as force_members_nt return as value;
                                    ^^^^^^^^^^^^^^^^

Perhaps the best reason for avoiding nested tables in a database is that they are hard to work with, and the syntax is underdocumented and hard to grok.

Moving on!

Here is a table with a nested table.

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>

As you can see, each element in the nested table the ID attribute is set to zero in all cases. What we would like to do is update all of them. But, alas!

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> 

It is possible to update all the elements on a nested table for a single row in the holding table:

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>

But the only way of doing that for the whole table is a PL/SQL loop. Yuck!

There is an alternative: use a Nested Table Locator, via the NESTED_TABLE_GET_REFS hint. This is a particularly obscure thing (it's not in the main list of hints) but it does the trick:

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>

This hint allows us to bypass the holding table altogether and work with the actual nested table. That is, the object specified in the Nested Table storage clause:

create table transformer_forces (
    force_name varchar2(10)
    , force_members transformers_nt)
nested table force_members store as force_members_nt return as value;
                                    ^^^^^^^^^^^^^^^^
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文