已知表route,字段和内容如下:
起始节点 终止节点 距离
a b 100
a c 150
a d 200
b e 300
b f 800
e g 100
e h 300
要求找出从节点a开始能到达的所有路径
1.创建表route,插入数据
CREATE TABLE route (
begin_node VARCHAR2(3),
end_node VARCHAR2(3),
distance NUMBER(4));
INSERT INTO route VALUES('a','b',100);
INSERT INTO route VALUES('a','c',150);
INSERT INTO route VALUES('a','d',200);
INSERT INTO route VALUES('b','e',300);
INSERT INTO route VALUES('b','f',800);
INSERT INTO route VALUES('e','g',300);
INSERT INTO route VALUES('e','h',300);
2.创建t_node类型
CREATE OR REPLACE TYPE t_node AS OBJECT (name VARCHAR2(3), distance NUMBER(5));
3.创建t_node_array类型,是t_node类型数组
CREATE OR REPLACE TYPE t_node_array IS TABLE OF t_node;
4.创建isloopnode(node t_node, nodes t_node_array, nodes_depth NUMBER)函数,判断node是否在nodes中出现过
CREATE OR REPLACE FUNCTION isloopnode(node t_node, nodes t_node_array, nodes_depth NUMBER)
RETURN BOOLEAN
IS
i NUMBER;
BEGIN
FOR i IN 1..nodes_depth LOOP
IF nodes(i).name = node.name THEN
RETURN TRUE;
END IF;
END LOOP;
RETURN FALSE;
END;
5.创建过程printpath来打印路径
CREATE OR REPLACE PROCEDURE printpath(nodes t_node_array, nodes_depth number)
AS
i NUMBER(4);
BEGIN
FOR i IN 1..nodes_depth LOOP
IF i<>1 THEN
DBMS_OUTPUT.PUT('-->');
END IF;
DBMS_OUTPUT.PUT(nodes(i).NAME||'[');
DBMS_OUTPUT.PUT(nodes(i).DISTANCE||']');
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
END;
6.遍历过程iterate
CREATE OR REPLACE PROCEDURE iterate(node IN t_node, nodesStack IN OUT t_node_array, stackDepth IN OUT NUMBER)
AS
nextNode t_node;
nextNodes t_node_array := t_node_array();
CURSOR c_route IS SELECT end_node,distance FROM route WHERE begin_node=node.name;
tempStr VARCHAR2(3);
tempInt number(4);
i number(4);
BEGIN
--将当前节点存入路径栈中
IF stackDepth = nodesStack.COUNT THEN
--需要扩展栈
nodesStack.EXTEND(1);
END IF;
stackDepth := stackDepth + 1;
nodesStack(stackDepth):= node;
--找开游标,查找后续节点
OPEN c_route;
FETCH c_route INTO tempStr, tempInt;
--没有后续节点
IF c_route%NOTFOUND THEN
--打印出本条线路
printpath(nodesStack, stackDepth);
CLOSE c_route;
--回归到上一节点
stackDepth := stackDepth - 1;
RETURN;
END IF;
--依次处理后续节点
--先将节点存到临时数组nextNodes,以期尽快关闭游标
WHILE c_route%FOUND LOOP
--路程要累积起来
nextNode := t_node(tempStr, nodesStack(stackDepth).distance + tempInt);
--存入临时数组
nextNodes.EXTEND(1);
nextNodes(nextNodes.COUNT) := nextNode;
FETCH c_route INTO tempStr, tempInt;
END LOOP;
CLOSE c_route;
FOR i IN 1..nextNodes.COUNT LOOP
nextNode := nextNodes(i);
--判断是否与路径上的先前节点重复
IF isloopnode(nextNode, nodesStack, stackDepth) THEN
--打印出本条线路
printpath(nodesStack, stackDepth);
--回归到上一节点
stackDepth := stackDepth - 1;
RETURN;
END IF;
--非重复节点
iterate(nextNode, nodesStack, stackDepth);
END LOOP;
--处理完毕本节点,回归到上一节点
stackDepth := stackDepth - 1;
END;
7.PL/SQL调用iterate
DECLARE
node t_node;
nodesstack t_node_array:=t_node_array();
stackdepth NUMBER(4);
BEGIN
node:=t_node('A', 0);
stackdepth:=0;
iterate(node,nodesstack,stackdepth);
END;
8.执行结果
a[0]-->b[100]-->e[400]-->g[700]
a[0]-->b[100]-->e[400]-->h[700]
a[0]-->b[100]-->f[900]
a[0]-->c[150]
a[0]-->d[200]
分享到:
相关推荐
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口——使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同...
另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口 使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同的感观...
另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口——使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同的...
至此,test_procedure存储过程已经完成,经过编译后就可以在其他PL/SQL块或者过程中调用了。 函数与过程具有很大的相似性,此处不再详述。 编辑本段 游标 游标的定义为:用游标来指代一个DML SQL操作返回的...
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口——使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同...
另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口——使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同...
/*test_procedure可以省略*/ 至此,test_procedure存储过程已经完成,经过编译后就可以在其他PL/SQL块或者过程中调用了。函数与过程具有很大的相似性,此处不再详述。 编辑本段游标 游标的定义为:用游标来指代一...
12.1.5 避免或者减少递归调用 341 12.1.6 ROWID优化应用 347 12.2 设法避免外因影响 350 12.2.1 Hint改写确保执行计划正确 350 12.2.2 避免子查询的错误执行计划 350 12.2.3 所在环境的资源不足等问题 351 ...
12.1.5 避免或者减少递归调用 341 12.1.6 ROWID优化应用 347 12.2 设法避免外因影响 350 12.2.1 Hint改写确保执行计划正确 350 12.2.2 避免子查询的错误执行计划 350 12.2.3 所在环境的资源不足等问题 351 ...
2.4.2 pl/sql程序结构 33 第3章 创建、修改和删除表 37 3.1 表的基础知识 37 3.1.1 表的基本结构 37 3.1.2 表的种类 38 3.2 sql数据类型 39 3.2.1 字符型数据 39 3.2.2 数字型数据 40 3.2.3 日期数据类型 41...
2.4.1 PL/SQL的特点 2.4.2 PL/SQL程序结构 第3章 创建、修改和删除表 3.1 表的基础知识 3.1.1 表的基本结构 3.1.2 表的种类 3.2 SQL数据类型 3.2.1 字符型数据 3.2.2 数字型数据 3.2.3 日期...
在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块,不过有一点不同的是,触发器是隐式调用的,并不能接收参数。 触发器优点 (1)触发器能够实施的检查和操作比主键和外键约束、...
), interpreted (然后 PL/SQL 模块将被编译为 PL/SQL 字节代码格式), debug (PL/SQL 模块将用探测调试符号来编译), non_debug。 默认值: " interpreted, non_debug " plsql_native_linker: 说明: 此参数指定链接...
10.2.5 将子查询因子化应用到PL/SQL中 270 10.3 递归子查询 273 10.3.1 一个CONNECT BY的例子 274 10.3.2 使用RSF的例子 275 10.3.3 RSF的限制条件 276 10.3.4 与CONNECT BY的不同点 276 10.4 复制CONNECT BY...
-- 首先,以超级管理员的身份登录oracle sqlplus sys/bjsxt as sysdba --然后,解除对scott用户的锁 alter user scott account unlock; ... --(默认全局数据库名orcl) 1、select ename, sal * 12 from ...