TSql CTE 递归原理探究

CTE是如何进行递归的?产生递归的条件有三个,分别是

  • 初始值
  • 自身调用自身
  • 结束递归的条件

1,示例代码

;with cte as
(
select 1 as id, 1 as jd 

union all

select id +1 as id ,jd+2 as jd
from cte
where id<10
)
select *
from cte

查询结果如下

2,递归过程分析

2.1 初始值

select 1 as id, 1 as jd 提供初始值,CTE中的值只有这一个。

2.2 第一次递归调用

select id +1 as id ,jd+2 as jd
from cte
where id<10

在第一次递归时,Cte的值只有初始值,递归调用之后, id=2,jd=3

2.3 第二次递归调用

第二次递归调用时,递归调用的CTE的值是 id=2, jd=3,递归调用之后,获得一个新行,id=3,jd=5

依次类推,每一次递归使用的CTE的值都是上一次递归改变的值。

2.4 递归结束

where id<10 ,递归结束之后,将所有的CTE的值进行 union all

递归结束的条件是 select 子句返回的查询结果为null,或达到maxrecursion的限制,即递归最大嵌套次数。

3,CTE 的最大递归次数

TSql默认的递归次数是100,也可以通过option提示来修改允许的递归次数。

;with cte as
(
select 1 as id, 1 as jd
union all

select id+1 as id, jd+2 as jd
from cte
--where id<10
)
select *
from cte
option(maxrecursion 10)

如果要允许无限制的递归嵌套,必须使用嵌套提示 option(maxrecursion 0)

当在查询执行期间达到指定或默认的 MAXRECURSION 数量限制时,Sql Server将结束查询并返回错误,如下

Msg 530, Level 16, State 1, Line 2
The statement terminated. The maximum recursion 10 has been exhausted before statement completion.

由于此错误,该语句的所有结果都被回滚。如果该语句为 SELECT 语句,则可能会返回部分结果或不返回结果。所返回的任何部分结果都可能无法包括超过指定最大递归级别的递归级别上的所有行。

所以,慎用maxrecursion 查询提示,在正式的代码中,不要使用。在测试代码中通过之后,去掉maxrecursion,通过where 条件来限制递归嵌套的次数。

时间: 2024-07-29 15:05:43

TSql CTE 递归原理探究的相关文章

《coredump问题原理探究》Windows版 笔记

<coredump问题原理探究>Windows版 笔记 Debug 一.环境搭建 1.Win7捕获程序dump 2.Windbg符号表设置(Symbols Search Path) 二.WinDbg命令 三.函数栈帧 1.栈内存布局 2.栈溢出 3.栈的规律 4.定位栈溢出问题的经验方法 四.函数逆向 五.C内存布局 1.基本类型 2.数组类型 3.结构体 六.C++内存布局 1.类的内存布局 2.this指针 3.虚函数表及虚表指针 4.单继承 5.多继承(无公共基类) 七.STL容器内存布

8第八章CTE递归及分组汇总高级部分(多维数据集)(转载)

8第八章CTE递归及分组汇总高级部分(多维数据集) 这里贴图太麻烦...算了 UNION 等集合操作符: UNION 等以第一个 SELECT  的 列明 作为 整个结果集的列明,整个结果集 唯一认可的 唯一逻辑处理阶段 是 ORDER BY 这个意思是说 只有 ORDER BY 是对整个结果集作用的,其它都操作都作用在 UINON 两侧的 子集合中. EXCEPT 操作符也是 提出了重复值的 此外,它认为两个 null 值是相等的, 而 NOT EXISTS 认为两个 null 值不相等, 集

python_递归原理

需要: 输出这样一些有规律数据: [0,1,1,2,3,5,8,13,21,34.......]看上面需要好像有一些规律,没错,就是大家熟悉的婓那波契数列,n=(n-1)+(n-2)如13=8+5: 运用递归原理得:def func(arg1,arg2): if arg1 == 0: print arg1,arg2 arg3 = arg1 + arg2 print arg3 if arg3 > 2046: return '' func(arg2,arg3) func(0,1)该函数在函数里再调用

Cocos2d-x 3.2:定时器的使用和原理探究(2)

Cocos2d-x 3.2:定时器的使用和原理探究(2) 本文转载至深入了解Cocos2d-x 3.x:定时器的使用和原理探究(2) 上一篇说到定时器的使用方法,这篇主要分析它的实现原理. 1.哈希链表 Cocos2d-x封装了一个结构体,叫做UT_hash_handle,只要在自定义的结构体中声明这个结构体变量,就实现了哈希链表,并且能使用一系列的哈希链表专用的宏.这个结构体的具体实现如下: 1 2 3 4 5 6 7 8 9 10 typedef struct UT_hash_handle 

Cocos2d-x 3.2:定时器的使用和原理探究(1)

Cocos2d-x 3.2:定时器的使用和原理探究(1) 本文转载至深入了解Cocos2d-x 3.x:定时器的使用和原理探究(1) 注:本文开始,引擎升级到Cocos2d-x 3.6 在游戏开发过程中,经常会遇到使用计时器的情况,例如:倒计时,定时炸弹等.scheduler是Cocos2d-x 2.x时代就已经存在的产物,主要用于各种延时函数以及各种每帧运行的函数.本文主要介绍scheduler的API函数以及使用方法. 首先,所有继承Node的类都可以使用scheduler,以下是Node类

zookeeper使用和原理探究(一)(转)

zookeeper介绍zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目中的一个子项目,并且根据google发表的<The Chubby lock service for loosely-coupled distributed systems>论文来实现的,接下来我们首先来安装使用下这个软件,然后再来探索下其中比较重要一致性算法. zookeeper安装和使用zookeeper的安装基本上可以按照 http://hadoop.apache.org/zookee

vmware nat模式原理探究,实现虚拟机跨网段管理

vmware nat模式原理探究: 理解nat模式,我们能更加了解主机与虚拟机之间如何通信,以及虚拟机如何实现上网. 以及便于我们分析虚拟机与主机无法通信和无法上外网的问题. 下面通过实战:虚拟网络拓扑,抓包分析. 为什么要探究nat模式? 从日常需求出发: 我们电脑上用到的虚拟机越来越多,需要固定IP,方便管理. 网络环境经常会变,我们可能在家办公和在公司办公网段不一样,每次要改为同一个网段再连接使用,比较麻烦. 首先理解vmware的三种模式: bridge模式:相当于一台hub,真实主机与

Cocos2d-x 3.2:定时器的使用和原理探究(3)

Cocos2d-x 3.2:定时器的使用和原理探究(3) 本文转载至[深入了解cocos2d-x 3.x]定时器(scheduler)的使用和原理探究(3) 上篇文章分析到了定时器的定义,这篇的重点就是定时器是如何运行起来的. 1.从main中寻找定时器的回调 讲定时器的运行,就不得不触及到cocos2dx的main函数了,因为定时器是主线程上运行的,并不是单独线程的,所以它的调用必然会在main函数中,每帧调用. 以下代码就是win32平台下的main函数 [cpp] view plainco

SQL CTE 递归 查询省,市,区

IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb create table tb(id varchar(3) , pid varchar(3) , name varchar(10)) insert into tb values('001' , null , '广东省') insert into tb values('002' , '001' , '广州市') insert into tb values('003' , '001' , '深圳市') inse