Oracle:用户数据中的Connect By循环

7

我了解当Oracle中可能出现循环的情况。理论上说,如果一条记录既是另一个节点的父节点,同时也是它的子节点,则它可能会进入循环。

但是我无法理解为什么我的这个特定查询会陷入循环。

SELECT Empno, Ename, Job
FROM Emp
START WITH Empno = 7839
CONNECT BY PRIOR
Job='PRESIDENT'

请有人能解释一下这些数据是如何导致循环的吗?我做了一个CONNECT_BY_ISCYCLE检查,并发现记录循环为KING(President)。但我仍然不明白它如何可能,因为KING是总裁,我没有看到它成为表中任何记录的子元素和父元素的方式。

请解释一下,为什么这是一个错误,循环在哪里?

预先感谢。

顺便说一下,该表是Oracle中SCOTT用户中默认的EMP表。

4个回答

10

添加表达式 nocycle connect by nocycle


6
要查找父行的子项,Oracle会对父行的PRIOR表达式和表中每一行的其他表达式进行评估。满足条件的行是该父行的子项。CONNECT BY条件可以包含其他条件以进一步过滤查询所选的行。
如果CONNECT BY条件在层次结构中导致循环,则Oracle将返回错误。如果一行既是另一行的父亲(或祖父或直接祖先),又是其子项(或孙子或直接后代),则会发生循环。
如果没有满足START WITH并且Job = 'PRESIDENT'的行,则循环永远不会发生(Oracle仅检索START WITH行)。
如果表中存在满足START WITH并且Job = 'PRESIDENT'的行,则无论如何都会发生循环,因为: 1. Oracle找到满足START WITH的所有行(根行)。 2. 对于p.1中的每一行,Oracle扫描整个表以查找后代。所有行(包括来自p.1的行)都满足CONNECT BY中的条件(因为prior Job = 'PRESIDENT'始终为真)。 3.显而易见...

嗨Multisync,我理解这个理论。我不明白的是,即使我只有一行Job='PRESIDENT',我仍然会得到循环错误。 - Manish
1
@Manish "Oracle在寻找后代时,会对父行的CONNECT BY条件中的PRIOR表达式进行评估,并对表中每一行执行其他表达式。" 当Oracle查找后代时,会扫描整个表。 - Multisync
谢谢你的回答。我现在明白了。 - Manish
@Manish 谢谢你。我的答案一开始是不正确的。 - Multisync

5
SELECT Empno, Ename, Job
FROM Emp
START WITH Empno = 7839
CONNECT BY nocycle PRIOR
Job='PRESIDENT'

0
在我的情况下,可能与你的情况有些不同。 但我希望它也可以帮助其他人。 因为我的老板没有数据,其他记录中也是EMPNO,所以它一直在循环运行。 我添加了一个条件来防止这个问题。
SELECT PRIOR BOSSNO, BOSSNO, EMPNO 
FROM Emp 
WHERE A.EMPNO   <> '7839' -- Add it here
START WITH BOSSNO = 7839 
CONNECT BY PRIOR CONNECT BY PRIOR A.EMPNO  = A.BOSSNO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接