Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 无法通过递归过程获得正确的输出_Oracle_Stored Procedures_Plsql - Fatal编程技术网

Oracle 无法通过递归过程获得正确的输出

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

我有一个叫做“测试表”的表。它有两列,分别命名为“父”和“子”,如下所示: 假设两列都是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
    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