Oracle CONNECT BY 行为

Oracle CONNECT BY behaviour

我以为我了解 Oracle CONNECT BY 的工作原理。

但后来我发现了这个。

select dual.*, CONNECT_BY_ISCYCLE from dual
connect by nocycle 1=1
and LEVEL <= 2
;

结果

DUMMY   CONNECT_BY_ISCYCLE
X       0
X       0

但是

select dual.*, CONNECT_BY_ISCYCLE from dual
connect by nocycle 1=1
and LEVEL <= 2
and prior dummy = dummy
;

只产生 1 行

DUMMY   CONNECT_BY_ISCYCLE
X       1

我希望得到与第一个查询相同的结果。

有人可以解释一下或指出我对此的解释吗?

这是在 Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

Oracle 如何在分层查询中识别 "cycles"?

如果记录在案,说明它做得不是很好。无论如何,我认为我们在 OTN 讨论中找到了正确且完整(而且非常简单)的答案:https://community.oracle.com/thread/3999985

无论如何:当您 运行 分层查询时,对于生成的每一行,Oracle 将查看由 中的 PRIOR 运算符 操作的列 =10=] 子句,并且仅针对这些列,以查看新生成的行是否与现有行匹配。

这就是 "select 5 from dual connect by level <= 100" 有效的原因,即使它生成相同的行 100 次。没有循环,因为 "cycle" 只查看 CONNECT BY 中 PRIOR 前面的列 - 并且有 none.

这也是为什么你会经常看到像connect by [other conditions here] and prior sys_guid() is not null这样的东西。 sys_guid() 永远不会为空;但是通过将它添加到 connect by,并且非常重要的是使用 PRIOR 运算符,您可以确保永远不会有循环(因为每次调用都保证 return 不同的值!)所以你可以通过 level 上的条件或其他方式自由打破 "infinite recursion",但不能通过 "cycles" 的标识。 (由于要检查这个额外的 "column",Oracle 永远不会看到循环。)