已知表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语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口——使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同的...
- **C、函数不能递归调用**:错误,函数可以递归调用,只要不超过系统限制。 - **D、以上说法都不对**:错误,选项B正确。 **4. 有一产品表(编号,名称,价格,数量,所属分类),下列语法不正确的是?** - **...
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编辑器,功能强大——该编辑器...
PL/SQL,全称为Procedural Language/Structured Query Language,是Oracle数据库提供的一种过程化编程语言,它...随着经验的积累,还可以深入学习更高级的主题,如游标、递归、并发控制等,进一步提升PL/SQL编程技能。
在"第七章.doc"中,你可能会学习到关于PL/SQL的更高级主题,比如递归、游标的高级用法、存储过程的参数传递、复合类型以及PL/SQL与数据库并发控制的机制。每个实例都是精心设计的,旨在帮助你理解和掌握这些概念,...
另外,还含有历史缓存,您可以轻松调用先前执行过的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相同...
- **递归调用**:理解如何在过程或函数中使用递归调用来解决复杂问题。 3. **游标和集合** - **游标**:使用游标处理单行或多行结果集,以实现动态查询。 - **集合类型**:如VARRAY和NESTED TABLE,用于存储一组...
"OracleOracle触发器与存储过程高级编程.rar"可能涵盖触发器和存储过程的高级话题,如游标、递归、动态SQL、游标变量等。“Oracle SQL必备参考.rar”可能包含SQL查询优化、联接操作、子查询、聚合函数等方面的内容。...
在这个过程中,你将接触到更多的概念,如游标、集合、记录类型、递归、游标变量、动态SQL等,这些都是PL/SQL的精华所在。 Oracle PL-SQL语言初级教程.pdf文件将深入探讨这些主题,通过实例讲解和练习,帮助初学者...
9. **高级特性**:可能涉及递归、事务控制、并行执行、PL/SQL对象类型(如对象、表、集合和指针)以及PL/SQL中的并发控制。 随书提供的源码可能包含了各种示例程序,帮助读者深入理解书中所讲的理论知识,并提供...
- 函数(FUNCTION):返回一个特定值的子程序,可以被其他PL/SQL代码或SQL查询调用。 4. 游标: 游标允许逐行处理查询结果集,通常用于在循环中处理多行数据。 5. 异常处理: 使用EXCEPTION关键字来捕获和处理...
/*test_procedure可以省略*/ 至此,test_procedure存储过程已经完成,经过编译后就可以在其他PL/SQL块或者过程中调用了。函数与过程具有很大的相似性,此处不再详述。 编辑本段游标 游标的定义为:用游标来指代一...