sql - 带有递归 SQL 查询的无限循环
问题描述
我似乎无法在此查询中找到无限循环背后的原因,也找不到如何纠正它。
这是上下文:我有一个名为 mergesWith 的表,其描述如下: mergesWith:有关邻近海域的信息。请注意,在这种关系中,对于每一对相邻的海洋 (A,B),只给出一个元组——因此,这种关系不是对称的。sea1:一片海 sea2:一片海。
我想通过导航了解从地中海可到达的每一个海洋。我选择了使用 "with" 的递归查询:
With
acces(p,d) as (
select sea1 as p, sea2 as d
from MERGESWITH
UNION ALL
select a.p, case when mw.sea1=a.d
then mw.sea2
else mw.sea1
end as d
from acces a, MERGESWITH mw
where a.d=mw.sea1 or a.d=mw.sea2)
select d
from acces
where p= 'Mediterranean Sea';
我认为原因要么是要么case when
不够a.d=mw.sea1 or a.d=mw.sea2
严格,但我似乎无法确定原因。
我收到此错误消息: 32044. 00000 -“执行递归 WITH 查询时检测到循环” *原因:递归 WITH 子句查询产生了一个循环,并被停止以避免无限循环。*行动:重写递归 WITH 查询以停止递归或使用 CYCLE 子句。
解决方案
循环是由查询的结构引起的,而不是由数据中的循环引起的。你问骑自行车的原因。这应该很明显:在第一次迭代中,一行输出具有d = 'Aegean Sea'
. 在第二次迭代中,您会发现一行带有d = 'Mediterranean Sea'
,对吗?你现在能看到这将如何导致循环吗?
递归查询有一个cycle
专门用于此类问题的子句。出于某种原因,即使是许多很好地学习了递归with
子句并一直使用它的用户,似乎也没有意识到该cycle
子句(以及不相关但同样有用的search
子句 - 用于对输出进行排序)。
在您的代码中,您需要进行两项更改。添加cycle
子句,并且仅在非循环行的外部查询过滤器中添加。在cycle
子句中,您可以决定如何调用“循环”列,以及赋予它什么值。为了使其看起来尽可能类似于connect by
查询,我喜欢调用新列IS_CYCLE
并为其赋予值 0(表示无循环)和 1(表示循环)。在下面的外部查询中,添加is_cycle
到select
列表以查看它添加到递归查询中的内容。
注意cycle
子句的位置:它紧跟在递归with
子句之后(特别是在递归因式子查询末尾的右括号之后)。
with
acces(p,d) as (
select sea1 as p, sea2 as d
from MERGESWITH
UNION ALL
select a.p, case when mw.sea1=a.d
then mw.sea2
else mw.sea1
end as d
from acces a, MERGESWITH mw
where a.d=mw.sea1 or a.d=mw.sea2)
cycle d set is_cycle to 1 default 0 -- add this line
select d
from acces
where p= 'Mediterranean Sea'
and is_cycle = 0 -- and this line
;
推荐阅读
- c - 使用'typedef'的正确方法是什么?
- python - 是否可以将“类型”类型的变量传递给组合框,以便集合的所有元素都是可选的?
- java - BufferedReader 没有读取整个文件
- r - 数据表中带条件的子集
- python - 使用几个硬编码过滤器在 Keras 中创建自定义 Conv2D 层?
- javascript - 在 React 组件 TS2532 中使用 axios 从 API 获取数据时如何停止未定义的属性
- python - 如何使用python找出样本均值在+/-一个总体均值单位内的概率为0.95的区间?
- javascript - (node.js)我如何调用这个中间件函数
- c# - 是否可以将 json 格式的文本转换为字符串而不会出错?(C#)
- java - 实现 ReduceFunction 时如何使用泛型类型