我们经常会遇到这样的场景,知道程序的入口A,然后A调用XX,XX调用XXX……,最后XN调用D,我们只知道A和D,想要找到这个调用链,比如

A-B-C-D

但是很多情况不是像这样的链表或者树,而是调用很复杂的图。如下图

为了模拟这个调用链,我们可以创建5个测试包。

CREATE OR REPLACE PACKAGE cux_test_d ISPROCEDURE test;
END cux_test_d;CREATE OR REPLACE PACKAGE BODY cux_test_d ISPROCEDURE test ISBEGINNULL;END;
END cux_test_d;
CREATE OR REPLACE PACKAGE cux_test_c ISPROCEDURE test;
END cux_test_c;CREATE OR REPLACE PACKAGE BODY cux_test_c ISPROCEDURE test ISBEGINcux_test_d.test;END;
END cux_test_c;
CREATE OR REPLACE PACKAGE cux_test_b ISPROCEDURE test;
END cux_test_b;CREATE OR REPLACE PACKAGE BODY cux_test_b ISPROCEDURE test ISBEGINcux_test_c.test;END;
END cux_test_b;
CREATE OR REPLACE PACKAGE cux_test_e ISPROCEDURE test;
END cux_test_e;CREATE OR REPLACE PACKAGE BODY cux_test_e ISPROCEDURE test ISBEGINcux_test_d.test;END;
END cux_test_e;
CREATE OR REPLACE PACKAGE cux_test_a ISPROCEDURE test_1;PROCEDURE test_2;
END cux_test_a;CREATE OR REPLACE PACKAGE BODY cux_test_a ISPROCEDURE test_1 ISBEGINcux_test_e.test;END;PROCEDURE test_2 ISBEGINcux_test_b.test;END;
END cux_test_a;

而这个依赖关系,用视图all_dependencies提现,如下:

(可能存在更好的调用视图,我只找到了这个)

这里有两点需要注意的地方

1.REFERENCED_NAME具有索引,而NAME不具有

2.Package Body CUX_TEST_C 调用了Package CUX_TEST_D,但是CUX_TEST_D的调用链仍旧是 Package Body调用其它,所以我们在处理的时候,需要把Package和Package Body当成同一个东西,我这里是都当成package 处理

而针对第一点,需要将我们的图变成下列形式(否则,用NAME查找下一个REFERENCED_NAME,没有索引了,所有查询都是全表扫描)

因为从D找到C比较容易,而C找D比较难

仿照JavaScript数据结构-7-2图深度优先搜索_香辣素毛肚的博客-CSDN博客

在我们编写递归的深度优先搜索方法,我们需要创建一个栈的数据结构

先创建一个数组对象

 create or replace type cux_items_type  is table of varchar2(4000);

然后编写我们的栈对象

CREATE OR REPLACE TYPE cux_stack_type AS OBJECT
(top   NUMBER,items cux_items_type,MEMBER PROCEDURE init(SELF IN OUT cux_stack_type),MEMBER FUNCTION is_empty RETURN BOOLEAN,MEMBER PROCEDURE push(SELF    IN OUT cux_stack_type,p_value IN VARCHAR2),MEMBER FUNCTION pop(SELF    IN OUT cux_stack_type,p_value OUT VARCHAR2) RETURN BOOLEAN)
CREATE OR REPLACE TYPE BODY cux_stack_type ISMEMBER PROCEDURE init(SELF IN OUT cux_stack_type) ISBEGINself.top   := 0;self.items := cux_items_type();END;MEMBER FUNCTION is_empty RETURN BOOLEAN ISBEGIN--PLSQL数组下标为1开始IF self.top = 0THENRETURN TRUE;ELSERETURN FALSE;END IF;END is_empty;MEMBER PROCEDURE push(SELF    IN OUT cux_stack_type,p_value IN VARCHAR2) ISBEGIN--可变长数组,不用考虑栈满self.top := self.top + 1;self.items.extend;self.items(self.top) := p_value;END push;MEMBER FUNCTION pop(SELF    IN OUT cux_stack_type,p_value OUT VARCHAR2) RETURN BOOLEAN ISBEGINIF self.top = 0THENRETURN FALSE; --栈空ELSEp_value  := self.items(self.top);self.top := self.top - 1;RETURN TRUE;END IF;END pop;
END;

测试一下

DECLAREstack     cux_stack_type;l_boolean BOOLEAN;l_value   VARCHAR2(240);
BEGINstack := NEW cux_stack_type(0,NULL);stack.init;stack.push(1);stack.push(2);stack.push(3);l_boolean := stack.pop(l_value);dbms_output.put_line(l_value);l_boolean := stack.pop(l_value);dbms_output.put_line(l_value);l_boolean := stack.pop(l_value);dbms_output.put_line(l_value);l_boolean := stack.pop(l_value);dbms_output.put_line(l_value);IF NOT l_booleanTHENdbms_output.put_line('栈空');END IF;
END;

现在可以开始DFS遍历了

创建视图

CREATE OR REPLACE VIEW CUX_ALL_DEPENDENCIES_V AS
SELECT "OWNER","NAME","TYPE","REFERENCED_OWNER","REFERENCED_NAME","REFERENCED_TYPE","REFERENCED_LINK_NAME","DEPENDENCY_TYPE"FROM (SELECT owner,NAME,CASEWHEN TYPE IN ('PACKAGE BODY','PACKAGE') THEN'PACKAGE'ELSETYPEEND TYPE,referenced_owner,referenced_name,CASEWHEN referenced_type IN ('PACKAGE BODY','PACKAGE') THEN'PACKAGE'ELSEreferenced_typeEND referenced_type,referenced_link_name,dependency_typeFROM all_dependencies)WHERE 1 = 1AND NOT (referenced_name = NAME AND referenced_type = TYPE ANDreferenced_owner = owner);

使package body=package

创建程序包

CREATE OR REPLACE PACKAGE cux_util_pub ISTYPE stacks_tbl IS TABLE OF cux_stack_type INDEX BY BINARY_INTEGER;PROCEDURE find_dependencies(p_start_name IN VARCHAR2,p_start_type IN VARCHAR2,p_start_owner IN VARCHAR2,p_end_name IN VARCHAR2,p_end_type IN VARCHAR2,p_end_owner IN VARCHAR2,p_status_code OUT VARCHAR2,p_msg        OUT VARCHAR2,p_stacks_tbl OUT stacks_tbl);PROCEDURE find_all_path(p_start_object_id IN NUMBER,p_end_object_id IN NUMBER,p_stack    IN OUT NOCOPY cux_stack_type,d            IN OUT NUMBER,p_stacks_tbl IN OUT NOCOPY stacks_tbl);
END cux_util_pub;
CREATE OR REPLACE PACKAGE BODY cux_util_pub IS--采用递归形式的深度优先搜索,可能会导致栈溢出,后期优化PROCEDURE find_dependencies(p_start_name  IN VARCHAR2,p_start_type  IN VARCHAR2,p_start_owner IN VARCHAR2,p_end_name    IN VARCHAR2,p_end_type    IN VARCHAR2,p_end_owner   IN VARCHAR2,p_status_code OUT VARCHAR2,p_msg         OUT VARCHAR2,p_stacks_tbl  OUT stacks_tbl) ISl_start_object_id NUMBER;l_end_object_id   NUMBER;--  l_path_tbl        path_tbl;d                 NUMBER := -1;l_start_type      VARCHAR2(240);l_end_type        VARCHAR2(240);l_stack           cux_stack_type;BEGIN--g_paths_tbl.delete;l_stack := NEW cux_stack_type(0,NULL);l_stack.init;l_start_type:=p_start_type;l_end_type:=p_end_type;IF p_start_type LIKE 'PACKAGE%'THENl_start_type := 'PACKAGE';END IF;IF p_end_type LIKE 'PACKAGE%'THENl_end_type := 'PACKAGE';END IF;BEGINSELECT d.object_idINTO l_start_object_idFROM sys.dba_objects dWHERE d.object_name = p_start_nameAND d.object_type = l_start_typeAND d.owner = p_start_owner;EXCEPTIONWHEN OTHERS THENp_status_code := 'E';p_msg         := '参数错误';return;END;BEGINSELECT d.object_idINTO l_end_object_idFROM dba_objects dWHERE d.object_name = p_end_nameAND d.object_type = l_end_typeAND d.owner = p_end_owner;EXCEPTIONWHEN OTHERS THENp_status_code := 'E';p_msg         := '参数错误';return;END;find_all_path(p_start_object_id => l_start_object_id,p_end_object_id   => l_end_object_id,p_stack           => l_stack,d                 => d,p_stacks_tbl      => p_stacks_tbl);p_status_code := 'S';END find_dependencies;--获取该顶点第一个边表FUNCTION get_first_starc(p_object_id IN NUMBER) RETURN NUMBER ISl_start_object_name  VARCHAR2(240);l_start_object_type  VARCHAR2(240);l_start_object_owner VARCHAR2(240);l_next_object_name   VARCHAR2(240);l_next_object_type   VARCHAR2(240);l_next_object_owner  VARCHAR2(240);l_object_id          NUMBER;BEGINSELECT d.object_name,d.object_type,d.ownerINTO l_start_object_name,l_start_object_type,l_start_object_ownerFROM dba_objects dWHERE d.object_id = p_object_id;/*    IF l_start_object_type LIKE 'PACKAGE' || '%'THEN--忽略package和package body区别l_start_object_type := 'PACKAGE';END IF;*/--没有链表,只能使用排序找下一个BEGINSELECT NAME,owner,TYPEINTO l_next_object_name,l_next_object_owner,l_next_object_typeFROM (SELECT a.name,a.owner,a.type,row_number() over(PARTITION BY 1 ORDER BY a.owner, a.name, a.type) row_numberFROM cux_all_dependencies_v aWHERE a.referenced_owner = l_start_object_ownerAND a.referenced_name = l_start_object_nameAND a.referenced_type LIKE l_start_object_type)WHERE row_number = 1;EXCEPTIONWHEN OTHERS THENRETURN NULL;END;/*    IF l_next_object_type LIKE 'PACKAGE' || '%'THEN--忽略package和package body区别l_next_object_type := 'PACKAGE';END IF;*/SELECT d.object_idINTO l_object_idFROM dba_objects dWHERE d.owner = l_next_object_ownerAND d.object_name = l_next_object_nameAND d.object_type = l_next_object_type;RETURN l_object_id;END get_first_starc;FUNCTION get_next_starc(p_parent_object_id IN NUMBER,p_son_object_id    IN NUMBER) RETURN NUMBER ISl_start_object_name  VARCHAR2(240);l_start_object_type  VARCHAR2(240);l_start_object_owner VARCHAR2(240);l_next_object_name   VARCHAR2(240);l_next_object_type   VARCHAR2(240);l_next_object_owner  VARCHAR2(240);l_object_id          NUMBER;l_son_object_name    VARCHAR2(240);l_son_object_type    VARCHAR2(240);l_son_object_owner   VARCHAR2(240);l_row_number         NUMBER;BEGINSELECT d.object_name,d.object_type,d.ownerINTO l_start_object_name,l_start_object_type,l_start_object_ownerFROM dba_objects dWHERE d.object_id = p_parent_object_id;/*  IF l_start_object_type LIKE 'PACKAGE' || '%'THEN--忽略package和package body区别l_start_object_type := 'PACKAGE';END IF;*/SELECT d.object_name,d.object_type,d.ownerINTO l_son_object_name,l_son_object_type,l_son_object_ownerFROM dba_objects dWHERE d.object_id = p_son_object_id;BEGINSELECT row_numberINTO l_row_numberFROM (SELECT a.name,a.owner,a.type,row_number() over(PARTITION BY 1 ORDER BY a.owner, a.name, a.type) row_numberFROM cux_all_dependencies_v aWHERE a.referenced_owner = l_start_object_ownerAND a.referenced_name = l_start_object_nameAND a.referenced_type = l_start_object_type)WHERE NAME = l_son_object_nameAND owner = l_son_object_ownerAND TYPE = l_son_object_type;EXCEPTIONWHEN OTHERS THENRETURN NULL;END;BEGINSELECT NAME,owner,TYPEINTO l_next_object_name,l_next_object_owner,l_next_object_typeFROM (SELECT a.name,a.owner,a.type,row_number() over(PARTITION BY 1 ORDER BY a.owner, a.name, a.type) row_numberFROM cux_all_dependencies_v aWHERE a.referenced_owner = l_start_object_ownerAND a.referenced_name = l_start_object_nameAND a.referenced_type = l_start_object_type)WHERE row_number = l_row_number + 1;EXCEPTIONWHEN OTHERS THENRETURN NULL;END;SELECT d.object_idINTO l_object_idFROM dba_objects dWHERE d.owner = l_next_object_ownerAND d.object_name = l_next_object_nameAND d.object_type = l_next_object_type;RETURN l_object_id;END get_next_starc;PROCEDURE print_stack_name(p_stack IN cux_stack_type) ISl_info VARCHAR2(4000);BEGINIF p_stack.top <> 0THENFOR i IN 1..p_stack.topLOOPBEGINSELECT d.owner || '.' || d.object_name || '(' || d.object_type || ')'INTO l_infoFROM dba_objects dWHERE d.object_id = p_stack.items(i);dbms_output.put(l_info || '->');EXCEPTIONWHEN OTHERS THENNULL;END;END LOOP;dbms_output.new_line;END IF;END print_stack_name;--BFS--package和package body 统一取package的 object_idPROCEDURE find_all_path(p_start_object_id IN NUMBER,p_end_object_id   IN NUMBER,p_stack           IN OUT NOCOPY cux_stack_type,d                 IN OUT NUMBER,p_stacks_tbl      IN OUT NOCOPY stacks_tbl) IS-- d NUMBER := -1; --路径长度-- l_path_tbl path_tbl; --路径数组TYPE hash_map IS TABLE OF NUMBER INDEX BY VARCHAR2(240);l_visited hash_map; --类似键值对,该节点是否已被访问--  -- l_paths_tbl paths_tbl; --记录所有类型数组p                NUMBER;w                NUMBER;l_current_index  NUMBER;l_visited_result NUMBER;l_pop_boolean    BOOLEAN;l_value          VARCHAR2(4000);BEGINd := d + 1;--  p_path_tbl(d) := p_start_object_id;--入栈p_stack.push(p_start_object_id);l_visited(p_start_object_id) := 1;IF p_start_object_id = p_end_object_idTHEN--当p_start_object_id_n=p_end_object_id 则表示找到了A-B路径--写入二维数组--数组实现不了,只能写入栈里了--   g_paths_tbl(g_paths_tbl.count) := p_path_tbl;--    print_object_name(p_path_tbl => p_path_tbl);--出栈p_stacks_tbl(p_stacks_tbl.count) := p_stack;l_pop_boolean := p_stack.pop(l_value);print_stack_name(p_stack=>p_stack);--p_path_tbl.DELETE;END IF;--p指向p_start_object_id的第一个临点p := get_first_starc(p_object_id => p_start_object_id);WHILE (p IS NOT NULL)LOOPw := p;BEGINl_visited_result := l_visited(w);EXCEPTIONWHEN OTHERS THENl_visited_result := 0;END;IF l_visited_result = 0THEN--该节点未访问过find_all_path(w,p_end_object_id,p_stack,d,p_stacks_tbl);p := get_next_starc(p_start_object_id,p);END IF;END LOOP;--出栈l_pop_boolean := p_stack.pop(l_value);l_visited(p_start_object_id) := 0;END find_all_path;
END cux_util_pub;

测试脚本

DECLAREp_status_code VARCHAR2(240);p_msg         VARCHAR2(240);p_stacks_tbl cux_util_pub.stacks_tbl;
BEGINcux_util_pub.find_dependencies(p_start_name  => 'CUX_TEST_D',p_start_type  => 'PACKAGE',p_start_owner => 'APPS',p_end_name    => 'CUX_TEST_A',p_end_type    => 'PACKAGE',p_end_owner   => 'APPS',p_status_code => p_status_code,p_msg         => p_msg,p_stacks_tbl=>p_stacks_tbl);dbms_output.put_line(p_status_code);dbms_output.put_line(p_msg);
END;

结果如下

上图的p_stacks_tbl变量,存储了所有路径的栈,将栈里的元素一个个弹出,就是正确的A-B-C-D顺序

该算法无法处理有向带环图,比如下面的例子

后期进行优化

这几天调试一下,发现无法处理带环图,是因为

1.访问数组 l_visited是一个局部变量,每次循环l_visited都是空的

2.不应该在发现start=end就出栈,因此新的包如下:

CREATE OR REPLACE PACKAGE cux_util_pub ISTYPE stacks_tbl IS TABLE OF cux_stack_type INDEX BY BINARY_INTEGER;TYPE hash_map IS TABLE OF NUMBER INDEX BY VARCHAR2(240);PROCEDURE find_dependencies(p_start_name  IN VARCHAR2,p_start_type  IN VARCHAR2,p_start_owner IN VARCHAR2,p_end_name    IN VARCHAR2,p_end_type    IN VARCHAR2,p_end_owner   IN VARCHAR2,p_status_code OUT VARCHAR2,p_msg         OUT VARCHAR2,p_stacks_tbl  OUT stacks_tbl);PROCEDURE find_all_path(p_start_object_id IN NUMBER,p_end_object_id   IN NUMBER,p_stack           IN OUT NOCOPY cux_stack_type,d                 IN OUT NUMBER,p_stacks_tbl      IN OUT NOCOPY stacks_tbl,p_visited         IN OUT NOCOPY hash_map);
END cux_util_pub;
CREATE OR REPLACE PACKAGE BODY cux_util_pub IS--采用递归形式的深度优先搜索,可能会导致栈溢出,后期优化PROCEDURE find_dependencies(p_start_name  IN VARCHAR2,p_start_type  IN VARCHAR2,p_start_owner IN VARCHAR2,p_end_name    IN VARCHAR2,p_end_type    IN VARCHAR2,p_end_owner   IN VARCHAR2,p_status_code OUT VARCHAR2,p_msg         OUT VARCHAR2,p_stacks_tbl  OUT stacks_tbl) ISl_start_object_id NUMBER;l_end_object_id   NUMBER;d                 NUMBER := -1;l_start_type      VARCHAR2(240);l_end_type        VARCHAR2(240);l_stack           cux_stack_type;l_visited         hash_map;BEGINl_stack := NEW cux_stack_type(0,NULL);l_stack.init;l_start_type := p_start_type;l_end_type   := p_end_type;IF p_start_type LIKE 'PACKAGE%'THENl_start_type := 'PACKAGE';END IF;IF p_end_type LIKE 'PACKAGE%'THENl_end_type := 'PACKAGE';END IF;BEGINSELECT d.object_idINTO l_start_object_idFROM sys.dba_objects dWHERE d.object_name = p_start_nameAND d.object_type = l_start_typeAND d.owner = p_start_owner;EXCEPTIONWHEN OTHERS THENp_status_code := 'E';p_msg         := '参数错误';RETURN;END;BEGINSELECT d.object_idINTO l_end_object_idFROM dba_objects dWHERE d.object_name = p_end_nameAND d.object_type = l_end_typeAND d.owner = p_end_owner;EXCEPTIONWHEN OTHERS THENp_status_code := 'E';p_msg         := '参数错误';RETURN;END;find_all_path(p_start_object_id => l_start_object_id,p_end_object_id   => l_end_object_id,p_stack           => l_stack,d                 => d,p_stacks_tbl      => p_stacks_tbl,p_visited         => l_visited);p_status_code := 'S';END find_dependencies;--获取该顶点第一个边表FUNCTION get_first_starc(p_object_id IN NUMBER) RETURN NUMBER ISl_start_object_name  VARCHAR2(240);l_start_object_type  VARCHAR2(240);l_start_object_owner VARCHAR2(240);l_next_object_name   VARCHAR2(240);l_next_object_type   VARCHAR2(240);l_next_object_owner  VARCHAR2(240);l_object_id          NUMBER;BEGINSELECT d.object_name,d.object_type,d.ownerINTO l_start_object_name,l_start_object_type,l_start_object_ownerFROM dba_objects dWHERE d.object_id = p_object_id;BEGINSELECT NAME,owner,TYPEINTO l_next_object_name,l_next_object_owner,l_next_object_typeFROM (SELECT a.name,a.owner,a.type,row_number() over(PARTITION BY 1 ORDER BY a.owner, a.name, a.type) row_numberFROM cux_all_dependencies_v aWHERE a.referenced_owner = l_start_object_ownerAND a.referenced_name = l_start_object_nameAND a.referenced_type LIKE l_start_object_type)WHERE row_number = 1;EXCEPTIONWHEN OTHERS THENRETURN NULL;END;SELECT d.object_idINTO l_object_idFROM dba_objects dWHERE d.owner = l_next_object_ownerAND d.object_name = l_next_object_nameAND d.object_type = l_next_object_type;RETURN l_object_id;END get_first_starc;FUNCTION get_next_starc(p_parent_object_id IN NUMBER,p_son_object_id    IN NUMBER) RETURN NUMBER ISl_start_object_name  VARCHAR2(240);l_start_object_type  VARCHAR2(240);l_start_object_owner VARCHAR2(240);l_next_object_name   VARCHAR2(240);l_next_object_type   VARCHAR2(240);l_next_object_owner  VARCHAR2(240);l_object_id          NUMBER;l_son_object_name    VARCHAR2(240);l_son_object_type    VARCHAR2(240);l_son_object_owner   VARCHAR2(240);l_row_number         NUMBER;BEGINSELECT d.object_name,d.object_type,d.ownerINTO l_start_object_name,l_start_object_type,l_start_object_ownerFROM dba_objects dWHERE d.object_id = p_parent_object_id;SELECT d.object_name,d.object_type,d.ownerINTO l_son_object_name,l_son_object_type,l_son_object_ownerFROM dba_objects dWHERE d.object_id = p_son_object_id;BEGINSELECT row_numberINTO l_row_numberFROM (SELECT a.name,a.owner,a.type,row_number() over(PARTITION BY 1 ORDER BY a.owner, a.name, a.type) row_numberFROM cux_all_dependencies_v aWHERE a.referenced_owner = l_start_object_ownerAND a.referenced_name = l_start_object_nameAND a.referenced_type = l_start_object_type)WHERE NAME = l_son_object_nameAND owner = l_son_object_ownerAND TYPE = l_son_object_type;EXCEPTIONWHEN OTHERS THENRETURN NULL;END;BEGINSELECT NAME,owner,TYPEINTO l_next_object_name,l_next_object_owner,l_next_object_typeFROM (SELECT a.name,a.owner,a.type,row_number() over(PARTITION BY 1 ORDER BY a.owner, a.name, a.type) row_numberFROM cux_all_dependencies_v aWHERE a.referenced_owner = l_start_object_ownerAND a.referenced_name = l_start_object_nameAND a.referenced_type = l_start_object_type)WHERE row_number = l_row_number + 1;EXCEPTIONWHEN OTHERS THENRETURN NULL;END;SELECT d.object_idINTO l_object_idFROM dba_objects dWHERE d.owner = l_next_object_ownerAND d.object_name = l_next_object_nameAND d.object_type = l_next_object_type;RETURN l_object_id;END get_next_starc;PROCEDURE print_stack_name(p_stack IN cux_stack_type) ISl_info VARCHAR2(4000);BEGINIF p_stack.top <> 0THENFOR i IN 1 .. p_stack.topLOOPBEGINSELECT d.owner || '.' || d.object_name || '(' || d.object_type || ')'INTO l_infoFROM dba_objects dWHERE d.object_id = p_stack.items(i);/*   SELECT d.object_nameINTO l_infoFROM dba_objects dWHERE d.object_id = p_stack.items(i);dbms_output.put(l_info || '->');*/EXCEPTIONWHEN OTHERS THENNULL;END;END LOOP;dbms_output.new_line;END IF;END print_stack_name;--BFS--package和package body 统一取package的 object_idPROCEDURE find_all_path(p_start_object_id IN NUMBER,p_end_object_id   IN NUMBER,p_stack           IN OUT NOCOPY cux_stack_type,d                 IN OUT NUMBER,p_stacks_tbl      IN OUT NOCOPY stacks_tbl,p_visited         IN OUT NOCOPY hash_map) IS-- d NUMBER := -1; --路径长度-- l_path_tbl path_tbl; --路径数组-- l_visited hash_map; --类似键值对,该节点是否已被访问--  -- l_paths_tbl paths_tbl; --记录所有类型数组p                NUMBER;w                NUMBER;l_current_index  NUMBER;l_visited_result NUMBER;l_pop_boolean    BOOLEAN;l_value          VARCHAR2(4000);l_object_name    VARCHAR2(240);BEGINd := d + 1;--  p_path_tbl(d) := p_start_object_id;--入栈p_stack.push(p_start_object_id);p_visited(p_start_object_id) := 1;IF p_start_object_id = p_end_object_idTHENp_stacks_tbl(p_stacks_tbl.count) := p_stack;--   l_pop_boolean := p_stack.pop(l_value);--这里不能出栈print_stack_name(p_stack => p_stack);END IF;--p指向p_start_object_id的第一个临点p := get_first_starc(p_object_id => p_start_object_id);/*  IF p_stack.has(p_start_object_id)THENNULL;END IF;*/WHILE (p IS NOT NULL)LOOPw := p;BEGINl_visited_result := p_visited(w);EXCEPTIONWHEN OTHERS THENl_visited_result := 0;END;IF l_visited_result = 0-- AND NOT p_stack.has(w)THEN--该节点未访问过find_all_path(w,p_end_object_id,p_stack,d,p_stacks_tbl,p_visited);END IF;p := get_next_starc(p_start_object_id,p);END LOOP;--出栈l_pop_boolean := p_stack.pop(l_value);p_visited(p_start_object_id) := 0;END find_all_path;
END cux_util_pub;

ORACLE DATABASE 深度优先搜索的实例相关推荐

  1. oracle 实例多一些的书,Oracle+Database+11g+PLSQL编程实战(书+源码)

    [实例简介] Oracle+Database+11g+PLSQL编程实战(书+源码) [实例截图] [核心代码] OracleDatabase11gPLSQL编程实战(书源码) ├── Oracle ...

  2. Oracle DataBase单实例使用ASM案例(2)--Oracle 11g之环境准备

    Oracle DataBase单实例使用ASM案例(2)--Oracle 11g之环境准备 系统环境: 操作系统:RedHat EL5(64) Oracle 软件:Oracle 11gR2.Oracl ...

  3. c++输出方块_C/C++编程笔记:DFS 深度优先搜索的基本思想,含实例讲解

    采用搜索算法解决问题时,需要构造一个表明状态特征和不同状态之间关系的数据结构,这种数据结构称为结点.不同的问题需要用不同的数据结构描述. 根据搜索问题所给定的条件,从一个结点出发,可以生成一个或多个新 ...

  4. 【深度优先搜索】一个实例+两张动图彻底理解 DFS | DFS 与 BFS 的区别 | 用 DFS 自动控制我们的小游戏

    前言: 在第一篇文章中(link),我们讨论了 如何用 pygame 写一个小游戏,并用键盘交互控制 .接下来,我们将分别用 DFS .BFS .DRL 实现自动控制.这篇文章讨论了什么是深度优先搜索 ...

  5. oracle数据库改名步骤,oracle 11g2 数据库改名详细解释 oracle数据库改名详解 oracle database 改名详解 dbname...

    前面讲过修改sid名字,虽然已经修改过了实例名(sid),但是数据库的名称(dbname还是原来的名称orcl) 下面详细描述,更改数据库名字的.详细过程如下: 1.更改存档日志,默认安装完的orac ...

  6. 5和6 objbc oracle_《Oracle Database 12c完全参考手册(第7版)(试读版)》

    图书目录: 第Ⅰ部分 数据库核心概念 第1章 Oracle Database 12c架构选件 3 1.1 数据库和实例 4 1.2 数据库技术 5 1.2.1 存储数据 6 1.2.2 数据保护 7 ...

  7. 甲骨文发布适用于 MongoDB 的 Oracle Database API;Chrome 和 Edge 互相“拉踩”;树莓派驱动程序现可在 Android 上运行 | 开源日报

    整理 | 宋彤彤 责编 | 屠敏 开源吞噬世界的趋势下,借助开源软件,基于开源协议,任何人都可以得到项目的源代码,加以学习.修改,甚至是重新分发.关注「开源日报」,一文速览国内外今日的开源大事件吧! ...

  8. 【MOS】中文文档列表 - Oracle Database (文档 ID 1533057.1)

    中文文档列表 - Oracle Database (文档 ID 1533057.1) 类型: 状态: 上次主更新: 上次更新: ANNOUNCEMENT PUBLISHED 2017-2-23 201 ...

  9. Installing Oracle Database 18c Using RPM Packages

    Oracle官方已放出18c企业版的RPM安装包,但仅限于单机版.相对于之前的版本,省去了前期规划配置的繁琐步骤. 1.下载Oracle RPM安装包 从官网选择rpm格式的安装包,下载即可.如下图: ...

最新文章

  1. 源代码从 300 行到 172,000 行,它用了 23 年
  2. C#到Java byte类型冲突的解决
  3. 数据表格搜索php代码_手把手教学:提取PDF各种表格文本数据(附代码)
  4. nginx用户认证访问
  5. springapplication.run运行多个应用_编程的十二要素应用宣言
  6. Kafka监控架构设计
  7. 英特尔核芯显卡控制面板没有了_核显和独显、集成显卡有什么区别
  8. 21南阳理工oj新生赛Round#5--这是一道防ak题
  9. 程序员一人对接四人郁闷吐槽:轮流指挥,只有我从天亮忙到天黑
  10. Python技能树测评之改进建议
  11. 【微信支付】小案例,Java版
  12. Java小项目(三)---汽车租赁系统(面向对象)
  13. AndroidQQ登录
  14. python怎么判断实数_检查python对象是否可以解释为实数[python]
  15. 二分图匹配Hopcroft-Carp算法介绍
  16. [区块链]区块链技术在教育领域的应用
  17. Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解
  18. bp暴力破解(转载)
  19. 消除代码中的 if-else/switch-case的正确姿势
  20. 为方便大家,我分析导出了些高速下载器捆绑软件的反安装reg,需要的可自行选择

热门文章

  1. 转载 用例设计之判定表
  2. 在VMware 10.0上安装NetBSD 1.0
  3. 遥望布达拉——DAY10 巴塘-海通兵站
  4. 在netlify上部署golang web应用
  5. 再解析下内核自旋锁和优先级翻转问题
  6. 简单的MIPS指令编译程序
  7. 【因果学习】贝叶斯网络结构学习方法
  8. python对数据进行统计分析_用Python结合统计学知识进行数据探索分析
  9. 贝叶斯方法及其应用(2)
  10. 复制链接到safari浏览器打开_ios系统通过safari添加到主屏幕后,打开子链接还会跳转到safari...