用于标识的递归SQL查询

时间:2016-04-28 16:02:52

标签: sql sql-server recursion

请参阅下面的DDL:

CREATE TABLE #MasterChild (MasterID decimal(25,0), ChildID decimal(25,0), ChildCreTime datetime)
insert into #MasterChild values (150021032000000173536533,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173571072,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173573651,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173574917,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173582487,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173604342,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173931636,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173935066,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173946207,150021032000000173952172,'2016-04-22 13:38:32.747')
insert into #MasterChild values (150021032000000173946207,150021032000000173954415,'2016-04-22 13:43:28.120')
insert into #MasterChild values (150021032000000173536533,150021032000000173954321,'2016-04-22 13:43:28.120')
insert into #MasterChild values (150021032000000173954321,150021032000000173954319,'2016-04-22 13:43:28.120')

和下面的SQL:

with GetAllMerges
as
(
select masterid,childid from #MasterChild where masterid=150021032000000173571072 and childid=150021032000000173946207
union all
select #MasterChild.masterid,#MasterChild.childid from #MasterChild inner join GetAllMerges
on  
#MasterChild.childid=GetAllMerges.masterid 
or (#MasterChild.childid=GetAllMerges.childid and #MasterChild.masterid<>GetAllMerges.masterid)  
) 
select distinct masterid,childid from GetAllMerges

我看到以下错误:

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

这是为什么?我试图展示所有链接的孩子和主人。例如,如果主1链接到子2,子2链接到主3,主3链接到子4而子4链接到主5,则1-5链接(所有子和主人都是人) )。

3 个答案:

答案 0 :(得分:3)

在您尝试执行此操作时,递归CTE的隐含MAXRECURSION为100,然后才会出错。

您可以使用OPTION (MAXRECURSION n)指定所需的递归次数WHERE n是介于0和32767之间的数字,0基本上意味着运行直到竞争,无论需要多长时间。

我不会在你的案例中提出这个建议

您的CTE似乎没有终止它的递归元素

  

错误组合的递归CTE 可能会导致无限循环。对于   例如,如果递归成员查询定义返回相同的内容   父列和子列的值,无限循环   创建。为了防止无限循环,您可以限制数量   通过使用,允许特定语句的递归级别   MAXRECURSION提示和OPTION中0到32,767之间的值   INSERT,UPDATE,DELETE或SELECT语句的子句。这让我们   您可以控制语句的执行,直到您解析代码   创建循环的问题。服务器范围的默认值为100。   指定0时,不应用限制。只有一个MAXRECURSION值   可以按语句指定。

(强调补充)

在更改MAXRECURSION设置之前,首先使用正确的递归CTE终止重写您的查询。

答案 1 :(得分:0)

让我看看我是否理解你的方法:

您正在编写(GetAllMerges)以显示所需的数据,并以递归方式将您引用的函数INSIDE吗?

==&GT; #MasterChild.childid = GetAllMerges.masterid&lt; ===

我认为你只是设置了一个无限循环。

我不确定为什么你不只是使用一段时间或一段时间来逐步完成链接键?

此外,当您的表名很长时,您可以而且应该使用别名。

答案 2 :(得分:0)

你应该在你的内部联接中切换孩子和parentid。像这样:

试一试

with GetAllMerges
as
(
select masterid,childid,1 AS RecLevel 
from #MasterChild 
where masterid=150021032000000173571072 and childid=150021032000000173946207
union all
select #MasterChild.masterid,#MasterChild.childid,GetAllMerges.RecLevel + 1 
from #MasterChild 
inner join GetAllMerges on #MasterChild.masterid=GetAllMerges.ChildID 
--or (#MasterChild.childid=GetAllMerges.childid and #MasterChild.masterid<>GetAllMerges.masterid)  
) 
select distinct masterid,childid from GetAllMerges

我评论了or (#MasterChild...,因为这会产生错误......请描述一下你想要实现的目标......