天天看點

oracle 中的遞歸查詢

本文整理自網絡:

一、樹型表結構:

  節點ID  上級ID  節點名稱

二、公式:

  select 節點ID,節點名稱,level

       from   表

       connect by prior 節點ID=上級節點ID

       start with 上級節點ID=節點值

      說明:

        1、常見的樹形結構為公司組織機構、地區……

    2、求節點ID以上的結構,或以上的結構,将“節點ID=上級節點ID”左右順序換一下即可。

    3、Level為Oracle的特殊字段,表示“層”的意思。目前節點ID的下一層節點為“1”。

     測試SQL:

            說明1、求002以下(或以上)所有子節點和層次(動态:總是從1開始算),但不包括自身

            說明2、如果求002以上的節點,則“connect by prior topno=departno”,“=”兩邊的條件換位即可。

            select departno,departname,level        

——level可以看做一個隐藏列,查出每一行所在的級别。

            from dept

            connect by prior departno=topno

            start with topno='002'; 

      測試資料

        create table Dept(

     DepartNO  varchar2(10),

          DepartName  varchar2(20),

          TopNo    varchar2(10));

          insert into Dept values('001',' 董事會','0');

    insert into Dept values('002','總裁辦 ','001');

   insert into Dept values('003','财務部 ','001');

   insert into Dept values('004','市場部 ','002');

   insert into Dept values('005','公關部 ','002');

   insert into Dept values('006','銷售部 ','002');

   insert into Dept values('007','分銷處 ','006');

   insert into Dept values('008','業務拓展處','004');

   insert into Dept values('009','銷售科','007');

  向前查 比如

  select distinct departno,departname,level

  from dept

  connect by prior topno=departno

  start with

  departno='005';

 那麼其實是查005自身以及上級, 是以結果是005,002,001

============================================================================================

       寫遞歸最關鍵的要定義出來 遞歸函數 ,遞歸函數 最關鍵的要定義出來它的 參數 .和它的 傳回值

       咱麼做展現,不用傳回值,直接做展現就行了,參數最重要,那就分析一下參數怎麼去定義?這時候要

       分析遞歸的過程,遞歸過程什麼樣呢?根據它的 id 找它的 父id,根據它的 父id 找到它的孩子,根據它

       的孩子再找到它的孩子.那麼分析這個參數肯定是一個id,因為隻有傳進來id,才知道怎麼去找這個id

       下面的孩子. 是以最關鍵定義出存儲過程的參數

       create or replace procedure p (v_pid article.pid%type, v_level binary_integer) is

         cursor c is select * from article where pid = v_pid;

         v_preStr varchar2(1024) := '';

       begin

         for i in 1..v_level loop

           v_preStr := v_preStr || '****';

         end loop;

         for v_article in c loop

           dbms_output.put_line(v_preStr || v_article.cont);

           if(v_article.isleaf = 0) then

             p (v_article.id, v_level + 1);

           end if;

       end;

       --展現emp表的樹狀結構

       create or replace procedure p

           (v_empno emp.empno%type, v_grade binary_integer)

       is

           cursor c is

                  select * from emp where mgr = v_empno;

           v_preStr varchar2(4000) := '';

              v_i binary_integer := 0;

           while v_i < v_grade loop

             v_preStr := v_preStr || '****';

                v_i := v_i + 1;

           end loop;

              for v_emp in c loop

                  dbms_output.put_line(v_preStr || v_emp.ename);

                     p(v_emp.empno, v_grade + 1); 

              end loop;

       declare

           v_emp emp%rowtype;

           select * into v_emp from emp where mgr is null;

              dbms_output.put_line(v_emp.ename);

              p(v_emp.empno, 1);

應用例子:

create or replace procedure aa(GlobalOrgId varchar2)

as

    i integer;

    S varchar2(2000);

begin

     S:='create global temporary table t(newGlobalParentOrgId varchar(40),newGlobalOrgId varchar(40),level int) ';

     execute immediate S;

     i:=i+1;

     Insert into t  select globalparentorgid,globalorgid,i from dept_table

                    where globalorgid = GlobalOrgId connect by prior globalorgid=globalparentorgid

                    start with globalparentorgid=GlobalOrgId;

     Insert into t  select c.globalparentorgid,c.globalorgid,i from dept_table c left join t d on c.globalparentorgid = d.newGlobalOrgId where d.level = i-1;

     select * from t;

end;