这可能是一种无需分层查询的方法。
他们让我头疼。
drop table connected_nodes;
create table connected_nodes (node_1 VARCHAR2(5),node_2 VARCHAR2(5));
INSERT INTO connected_nodes VALUES('A','B');
INSERT INTO connected_nodes VALUES('B','A');
INSERT INTO connected_nodes VALUES('B','C');
INSERT INTO connected_nodes VALUES('A','C');
INSERT INTO connected_nodes VALUES('C','D');
commit;
drop table links;
create table links
(from_node_1 VARCHAR2(5),
from_node_2 VARCHAR2(5),
to_node_1 VARCHAR2(5),
to_node_2 VARCHAR2(5),
first_node_1 VARCHAR2(5),
first_node_2 VARCHAR2(5),
link_num NUMBER);
drop table paths;
create table paths as select * from links;
create or replace procedure get_paths(p_node_1 VARCHAR2,p_node_2 VARCHAR2)
as
prev_num_links number;
num_links number;
begin
-- get first links in paths
insert into links
select
NULL,
NULL,
cn.node_1,
cn.node_2,
cn.node_1,
cn.node_2,
1
from
connected_nodes cn
where
cn.node_1 = p_node_1;
-- loop until number of path links does not increase
prev_num_links := 0;
loop
select count(*) into num_links from links;
if num_links = prev_num_links then
exit;
end if;
-- add new links
insert into links
select
l.to_node_1,
l.to_node_2,
c.node_1,
c.node_2,
l.first_node_1,
l.first_node_2,
l.link_num+1
from connected_nodes c,links l
where
l.to_node_2 = c.node_1 and
l.to_node_2 <> p_node_2 and
(l.to_node_1,
l.to_node_2,
c.node_1,
c.node_2) not in
(select
from_node_1,
from_node_2,
to_node_1,
to_node_2
from links);
commit;
prev_num_links := num_links;
end loop;
-- populate paths table with links that go backward
-- from end node to beginning.
-- add end nodes
insert into paths
select * from links
where to_node_2 = p_node_2;
-- loop until number of paths rows does not increase
prev_num_links := 0;
loop
select count(*) into num_links from paths;
if num_links = prev_num_links then
exit;
end if;
-- add new links
insert into paths
select
*
from links l
where
(l.to_node_1,
l.to_node_2,
l.first_node_1,
l.first_node_2,
l.link_num+1)
in
(select
from_node_1,
from_node_2,
first_node_1,
first_node_2,
link_num
from paths) and
(l.from_node_1,
l.from_node_2,
l.to_node_1,
l.to_node_2,
l.first_node_1,
l.first_node_2,
l.link_num)
not in
(select * from paths);
commit;
prev_num_links := num_links;
end loop;
end;
/
show errors
execute get_paths('A','C');
select
to_node_1,to_node_2,link_num,first_node_1,first_node_2
from paths
order by first_node_1,first_node_2,link_num;
输出如下所示:
TO_NO TO_NO LINK_NUM FIRST FIRST
----- ----- ---------- ----- -----
A B 1 A B
B C 2 A B
A C 1 A C
first_node_1 和 first_node_2 列
定义路径和 link_num 列
是它在路径中的哪个链接。
它又长又乱。可能是我没有处理的情况。
我想使用分层查询,除非你不能。这是一
尝试在没有它们的情况下使用 SQL 和 PL/SQL。