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;
/
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;
/
CODE:
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
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