dep
という単語 2番目のクエリ(union
の後) )があいまいです。実際には、rdeps
の列として解釈されます。 、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;
これが、クエリが無限のループを作成する理由です。エイリアスを変更することでこれを修正できます:
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)
または、より良いのは、善良な主が意図したように、列を使用するだけです。
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;
質問の最初のクエリは、再帰クエリによって生成された異なる(並列)ブランチ間の通信がないため、プレーンSQLで実行できるすべてです。機能的なアプローチでは、すべてのブランチに共通のストアとして一時テーブルを使用できます。関数は次のようになります:
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 $$;
使用法:
create temp table temp_table(id int);
select rec_function(4);
select *
from temp_table;