请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于公共表达式,recursive自引用为啥会触发循环

WITH RECURSIVE test AS (
SELECT 1 AS n
UNION ALL
SELECT 1+n FROM test WHERE n < 10
)
SELECT * FROM test ;
老师,我还是不理解为什么自引用能触发循环,如果多次调用了这个表达式本身,不是会产生多个1吗?,还有就是如果在工作中使用公共表表达式不小心漏写了限制条件引发了死循环,会不会导致服务器死机

正在回答 回答被采纳积分+3

1回答

sqlercn 2019-11-12 09:55:45

首先来说在公共表表达式中如果不小心写了死循环是不会引发宕机的,因为数据库本身可能通过max_sp_recursion_depth变量对循环是有最大次数限制的。那么既然知道是对一个表达式的循环,那么在这个表达式中n是一个变量,是会随着嵌套调用而累加的。所以才会出现一开始是n=1 而后就是n=n+1这样的累加效果。 

0 回复 有任何疑惑可以回复我~
  • 提问者 慕莱坞3268959 #1
    老师,我还是有个疑惑:
    如果第一个SELECT(SELECT 1 AS n)生成cte的初始行,应该表达式中产生一行n=1的数据,此时执行第二个select(SELECT 1+n FROM test WHERE n < 10)
    第一种想法:他是直接调用这个cte中的n=1的数据去执行 n+1得到了2,但是为什么会无限循环下去,是mysql本身的机制,自引用会产生递归,无限循环下去直到返回空值吗?因为我看你写评论树的公共表表达式没有写限制条件
    第二种想法:如果是再次执行了这个表达式,那第一个select 又会再执行一次,那么不是会产生多个1么?
    这是我的两种想法,请问我是不是想错了
    回复 有任何疑惑可以回复我~ 2019-11-12 21:10:28
  • sqlercn 回复 提问者 慕莱坞3268959 #2
    其实这就是一个递归调用,直到递归的条件不成立时就会退出调用。其实你可以把test看做一个表,第一次调用这个表中列n的值是1,下次调用这个表中列n值就是2,每一次都是更新虚拟表test中列的值,调用结束后返回表的最终值。
    回复 有任何疑惑可以回复我~ 2019-11-13 09:58:24
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信