Slovo dep
ve druhém dotazu (po union
) je nejednoznačný. Ve skutečnosti je interpretován jako sloupec rdeps
, nikoli jako alias objectdependencies.
with recursive rdeps as (
select dep
from objectdependencies dep
where dep.dependson = 4 -- starting point
union all
select dep -- this means r.dep
from objectdependencies dep
join rdeps r
on (r.dep).id = dep.dependson
) select (dep).id from rdeps;
To je důvod, proč dotaz vytváří nekonečnou smyčku. Můžete to opravit změnou aliasu:
with recursive rdeps as (
select dep
from objectdependencies dep
where dep.dependson = 4 -- starting point
union all
select objectdep
from objectdependencies objectdep
join rdeps r
on (r.dep).id = objectdep.dependson
) select (dep).id from rdeps;
id
----
1
2
3
1
2
1
(6 rows)
Nebo lépe, jen pomocí sloupců, jak to zamýšlel dobrý Pán:
with recursive rdeps as (
select id, dependson
from objectdependencies
where dependson = 4
union all
select d.id, d.dependson
from objectdependencies d
join rdeps r
on r.id = d.dependson
)
select *
from rdeps;
První dotaz v otázce je vše, co můžete udělat v prostém SQL, protože neexistuje žádná komunikace mezi různými (paralelními) větvemi generovanými rekurzivním dotazem. Ve funkčním přístupu můžete použít dočasný stůl jako úložiště společný pro všechny pobočky. Funkce může vypadat takto:
create or replace function rec_function(int)
returns void language plpgsql as $$
declare
i int;
begin
for i in
select id
from objectdependencies
where dependson = $1
loop
if not exists(
select from temp_table
where id = i)
then
insert into temp_table values(i);
perform rec_function(i);
end if;
end loop;
end $$;
Použití:
create temp table temp_table(id int);
select rec_function(4);
select *
from temp_table;