Từ dep
trong truy vấn thứ hai (sau union
) là mơ hồ. Trên thực tế, nó được hiểu là cột của rdeps
, không phải là bí danh của 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;
Đây là lý do tại sao truy vấn tạo ra một vòng lặp vô tận. Bạn có thể sửa lỗi này bằng cách thay đổi bí danh:
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)
Hoặc tốt hơn, chỉ bằng cách sử dụng các cột, giống như Chúa nhân lành đã định:
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;
Truy vấn đầu tiên trong câu hỏi là tất cả những gì bạn có thể làm trong sql đơn giản vì không có giao tiếp giữa các nhánh (paralel) khác nhau được tạo bởi truy vấn đệ quy. Trong cách tiếp cận chức năng, bạn có thể sử dụng một bảng tạm thời như một cửa hàng chung cho tất cả các chi nhánh. Hàm có thể trông như thế này:
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 $$;
Cách sử dụng:
create temp table temp_table(id int);
select rec_function(4);
select *
from temp_table;