create or replace package hierarchy is
  type strtabletype is table of varchar2(4000) index by binary_integer;
  strtable strtabletype;
  type numtabletype is table of number index by binary_integer;
  numtable numtabletype;
  function sys_connect_by_path(p_level     in number,
                               p_value     in varchar2,
                               p_delimiter in varchar2 default ',')
    return varchar2;
  function sys_sum_by_path(p_level in number, p_value in number)
    return number;
  pragma restrict_references(sys_connect_by_path, wnds);
  pragma restrict_references(sys_sum_by_path, wnds);
end;
/

create or replace package body hierarchy is
  ls_ret varchar2(4000);
  ln_ret number;
  function sys_connect_by_path(p_level     in number,
                               p_value     in varchar2,
                               p_delimiter in varchar2 default ',')
    return varchar2 is
  begin
    strtable(p_level) := p_value;
    ls_ret := p_value;
    for i in reverse 1 .. p_level - 1 loop
      ls_ret := strtable(i) || p_delimiter || ls_ret;
    end loop;
    return ls_ret;
  end;

  function sys_sum_by_path(p_level in number, p_value in number)
    return number is
  begin
    numtable(p_level) := p_value;
    ln_ret := p_value;
    for i in reverse 1 .. p_level - 1 loop
      ln_ret := numtable(i) + ln_ret;
    end loop;
    return ln_ret;
  end;
end;
/



select rpad(' ', 4 * level, ' ') || ename emp_name,
       sal,
       hierarchy.sys_connect_by_path(level, sal, '/') sal_path,
       hierarchy.sys_sum_by_path(level, sal) sal_sum
  from emp
start with mgr is null
connect by prior empno = mgr;

EMP_NAME                             SAL SAL_PATH                          SAL_SUM
------------------------------ --------- ------------------------------ ----------
    KING                         5000.00 5000                                 5000
        JONES                    2975.00 5000/2975                            7975
            SCOTT                3000.00 5000/2975/3000                      10975
                ADAMS            1100.00 5000/2975/3000/1100                 12075
            FORD                 3000.00 5000/2975/3000                      10975
                SMITH             800.00 5000/2975/3000/800                  11775
        BLAKE                    2850.00 5000/2850                            7850
            ALLEN                1250.00 5000/2850/1250                       9100
            WARD                 1250.00 5000/2850/1250                       9100
            MARTIN               1250.00 5000/2850/1250                       9100
            TURNER               1500.00 5000/2850/1500                       9350
            JAMES                 950.00 5000/2850/950                        8800
        CLARK                    2450.00 5000/2450                            7450
            MILLER               1300.00 5000/2450/1300                       8750

14 rows selected
posted on 2009-03-01 21:27  Oracle  阅读(851)  评论(0编辑  收藏  举报