如何在查询中取消嵌套嵌套表的集合?
Posted
技术标签:
【中文标题】如何在查询中取消嵌套嵌套表的集合?【英文标题】:How can I unnest a collection of nested tables in a query? 【发布时间】:2011-02-16 03:55:32 【问题描述】:我有一个过程,它通过 ODP.Net 接受类似于 parent_arr 的输入,作为来自应用层的输入。在该过程的第一步中,我将数组中的数据存储在一个全局临时表中,这样我就可以使用集合逻辑而不是 pl/sql 循环继续执行以下几个步骤。只要数组只有一个 parent_typ 成员,一切都很好。但是,当有多个成员时,我得到 ORA-01427,单行查询返回多行。下面的查询返回两个集合。我需要将两个集合取消嵌套在一个将显示 child.name 和 child.value 的 sql 语句中。怎么办?
示例对象
create type child_typ is object( name varchar2(100), value number );
create type child_arr is table of dropme_child_typ;
create type parent_typ is object( pname varchar2(100), child dropme_child_arr );
create type parent_arr is table of dropme_parent_typ;
下面的查询会抛出 ORA-01427
select * from table(
select child
from table( parent_arr(
parent_typ( 'TEST1',
child_arr(
child_typ( 'C1', 1 ),
child_typ( 'C2', 2 ) ) ),
parent_typ( 'TEST2',
child_arr(
child_typ( 'C3', 3 ),
child_typ( 'C4', 4 ) ) ) ) ) );
此查询有效,但返回对象 child_arr 的列
select child
from table( parent_arr(
parent_typ( 'TEST1',
child_arr(
child_typ( 'C1', 1 ),
child_typ( 'C2', 2 ) ) ),
parent_typ( 'TEST2',
child_arr(
child_typ( 'C3', 3 ),
child_typ( 'C4', 4 ) ) ) ) );
此查询失败,因为我无法访问“child”中的值
select child.name, child.value from
table( parent_arr(
parent_typ( 'TEST1',
child_arr(
child_typ( 'C1', 1 ),
child_typ( 'C2', 2 ) ) ),
parent_typ( 'TEST2',
child_arr(
child_typ( 'C3', 3 ),
child_typ( 'C4', 4 ) ) ) ) );
请告诉我有一种方法可以在不使用 pl/sql 循环的情况下执行此操作(这是迄今为止我能够成功的唯一方法)。速度是最重要的。我尝试使用 forall 语句循环访问 parent_arr 的成员,但它会引发批量绑定错误。
【问题讨论】:
【参考方案1】:您可以使用 lateral join 取消嵌套您的子对象:
SQL> WITH my_data AS (
2 SELECT pname, child
3 FROM TABLE(parent_arr(parent_typ('TEST1',
4 child_arr(child_typ('C1', 1),
5 child_typ('C2', 2))),
6 parent_typ('TEST2',
7 child_arr(child_typ('C3', 3),
8 child_typ('C4', 4)))))
9 )
10 SELECT my_data.pname, child.name, child.value
11 FROM my_data, table(my_data.child) child;
PNAME NAME VALUE
-------- ----- ----------
TEST1 C1 1
TEST1 C2 2
TEST2 C3 3
TEST2 C4 4
这是一种外连接形式,您可以将父级与其子级连接起来。
【讨论】:
有效。非常感谢。我正在追求 cast( multiset( ... 今天早上,我认为这肯定会奏效。 我只是在那个简单的语句上运行解释计划,成本非常高。我将不得不使用这个以及 pl/sql 循环和跟踪来查看哪个更具成本效益。感谢您为我提供替代解决方案! @Thomas:成本很高,因为 Oracle 没有关于这些对象的任何统计信息,因此它会猜测元素的数量(在 oracle 10.2.0.3 中,8168 个父母每个都有 8168 个孩子)。在这种情况下,成本并不能很好地指示查询的预期响应时间。我认为这个 SQL 会比 PL/SQL 循环执行得更好,不过,如果你能发布你的基准测试结果会很有趣。以上是关于如何在查询中取消嵌套嵌套表的集合?的主要内容,如果未能解决你的问题,请参考以下文章