Oracle 无法通过递归过程获得正确的输出
我有一个叫做“测试表”的表。它有两列,分别命名为“父”和“子”,如下所示: 假设两列都是Varchar2类型Oracle 无法通过递归过程获得正确的输出,oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,我有一个叫做“测试表”的表。它有两列,分别命名为“父”和“子”,如下所示: 假设两列都是Varchar2类型 PARENT CHILD --------------------- 50-100 10-001 50-100 10-002 50-100 10-003 50-100 11-100 50-100 11-101 11-100 10-100 11-100 10-101
PARENT CHILD
---------------------
50-100 10-001
50-100 10-002
50-100 10-003
50-100 11-100
50-100 11-101
11-100 10-100
11-100 10-101
11-100 10-102
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
我需要以这样的方式编写一个递归过程:如果给定父对象的子对象以“10”开头,那么它将被打印出来。
如果子值以“11”开头,则将对每个以11开头的子值递归调用该过程。
以下是所需的示例输出:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
以下是示例程序:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
create or replace type type_test2 as table of varchar2(2000);
create or replace procedure test_proc
(parent_data in type_test2,child_data out type_test2)
as
v_out type_test2:=type_test2();
begin
child_data:=type_test2();
select child
bulk collect into v_out
from test_table
where parent in(select * from table(parent_data));
for i in 1..v_out.count loop
child_data.extend(i);
v_out.extend(i);
if v_out(i) like '10-%' then
child_data(i):=v_out(I);
elsif v_out(i) like '11-%' then
test_proc(v_out,child_data);
end if;
end loop;
end;
/
declare
a type_test2:=type_test2('50-100');
b type_test2:=type_test2();
begin
test_proc(a,b);
for i in 1..b.count loop
dbms_output.put_line(b(I));
end loop;
end;
/
执行上述程序:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
create or replace type type_test2 as table of varchar2(2000);
create or replace procedure test_proc
(parent_data in type_test2,child_data out type_test2)
as
v_out type_test2:=type_test2();
begin
child_data:=type_test2();
select child
bulk collect into v_out
from test_table
where parent in(select * from table(parent_data));
for i in 1..v_out.count loop
child_data.extend(i);
v_out.extend(i);
if v_out(i) like '10-%' then
child_data(i):=v_out(I);
elsif v_out(i) like '11-%' then
test_proc(v_out,child_data);
end if;
end loop;
end;
/
declare
a type_test2:=type_test2('50-100');
b type_test2:=type_test2();
begin
test_proc(a,b);
for i in 1..b.count loop
dbms_output.put_line(b(I));
end loop;
end;
/
但我只得到5个子值,而不是6个值。缺少“10-100”
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
请帮助我获得正确的输出。不要递归调用该过程;而是使用单个分层查询:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
程序:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
CREATE PROCEDURE test\u proc(
测试表中的i\u父项。父项%TYPE,
o_儿童输出类型_测试2
)
作为
开始
选择子对象
批量收集到o_儿童中
从测试表
那里的孩子喜欢‘10%’
从parent=i\u parent开始
通过NOCYCLE连接
先前的孩子=父母
和先前的儿童型"11%",;
结束;
/
执行:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
声明
b type_test2:=type_test2();
开始
测试程序('50-100',b);
对于1..b.计数循环中的i
DBMS_OUTPUT.PUT_行(b(i));
端环;
结束;
/
输出:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
哪些产出:
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
然而,如果数据中存在一个循环,那么这可能会陷入无限循环中。上面的分层查询将检测循环并停止迭代(或者如果删除NOCYCLE
关键字将引发异常)
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102
DBFIDLE一个问题,为什么我们不能通过递归过程获得正确的输出。谢谢您的回答。我们如何避免上述过程中的无限循环?@Rohan使用分层查询而不是过程,因为这样会更有效,并使用
NOCYCLE
关键字来检测和防止循环。如果您坚持使用递归过程,那么您需要手动添加一些代码来检测循环,然后再递归到循环中;您可能需要将在每个级别找到的子级传递到递归过程和过滤器中,以从子代的结果中删除以前的结果,但我认为如果您想进一步探讨这个问题,最好问一个新问题。
CHILD
--------------
10-001
10-002
10-003
10-100
10-101
10-102