goto 与 start with ... connect by prior [nocyle]

1.在存储过程中看到一个 <<lastsql>>

在oracle群里,有个好心的兄弟帮忙解惑

原来是标签,用于goto时跳转的标识

语法 

goto  标签名

......

<<标签名>>

......

 

2.start with

connect by prior这个是用于树查询,可以查到节点的子节点或者父节点

语法

select 

from

[where]

start with

connect by prior

如:查询id为1所管理的员工(即,查询节点的子节点)

select id,managerid

from emp

start with id=1

connect by prior id=managerid(如果是managerid=id,则是查询节点的父节点)

 

刚学到了这个,很兴奋,马上试验,却提示了一个错误"结果是 ORA-01436: 用户数据中的 CONNECT BY 循环"

原来是

"树状一般都是在一条记录中记录一个当前节点的ID和这个节点的父ID来实现。但是,一旦数据中出现了循环记录,如两个节点互为对方父节点,系统就会报ORA-01436错误"

但在connect by后加一个nocycle,即可避免报错

 

以下摘自diybl的一篇文章http://www.diybl.com/course/7_databases/oracle/oraclejs/200798/70931.html#

为 了更好的查询一个树状结构的表,在Oracle的PL/SQL中提供乐一个诱人的特性——CONNECT BY子句。它大大的方便了我们查找树状表:遍历一棵树、寻找某个分支......,但还是存在一些不足。在Oracle 10G,就对这个特性做了增强。下面就举例说明一下。

CONNECT_BY_ISCYCLE
树状一般都是在一条记录中记录一个当前节点的ID和这个节点的父ID来实现。但是,一旦数据中出现了循环记录,如两个节点互为对方父节点,系统就会报ORA-01436错误,例如:

如果有这样的数据


insert into t_tonedirlib(dirindex, fatherindex, dirname, status) values (666, 667, '123', 5);insert into t_tonedirlib(dirindex, fatherindex, dirname, status) values (667, 666, '456', 5);执行这样的查询


select dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname from t_tonedirlibstart with fatherindex = 666connect by   fatherindex =   prior dirindex;结果是 ORA-01436: 用户数据中的 CONNECT BY 循环。


10G中,可以通过加上NOCYCLE关键字避免报错。并且通过CONNECT_BY_ISCYCLE属性就知道哪些节点产生了循环

select CONNECT_BY_ISCYCLE, dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirnamefrom t_tonedirlibstart with fatherindex = 666connect by NOCYCLE fatherindex =   prior dirindexCONNECT_BY_ISCYCLE DIRINDEX FATHERINDEX RPAD(' ',2*(LEVEL-1))||dirname;----------------- ---------------- ---------------------------------                  0                    667                    666 456                  1                    666                    667 1232 rows selectedCONNECT_BY_ISLEAF
查找树状表中的叶子节点不是件容易事。可以给表增加了一个字段来描述这个节点是否为叶子节点来解决问题,但这样做有很大的弊端:需要通代码逻辑来保证这个字段的正确性。
Oracle 10G中提供了一个新特性 CONNECT_BY_ISLEAF 来解决这个问题。简单点说,这个属性结果表明当前节点在满足条件的查询结果中是否为叶子节点, 0不是,1是。




select CONNECT_BY_ISLEAF, dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname   from t_tonedirlibstart with fatherindex = 0connect by   fatherindex =   prior dirindexCONNECT_BY_ISLEAF DIRINDEX FATHERINDEX RPAD(' ',2*(LEVEL-1))||dirname查询结果清晰明了!


----------------- ---------------- --------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值