当我在查询下运行时,我会收到此错误。即使我使用选项(maxrecursion 0),它也不会失败,但需要很长时间,但仍然无法看到它完成。所以我必须修复我的递归代码或需要相同而不递归。基本上有两个表,一个是员工,另一个是他们的合同。同一父母下的每个雇员都可以签订一份合同(父母可以拥有或者孩子可以拥有。但这并不重要,但他们只能拥有一份。这意味着同一家庭有一行(一份合同))。我需要获得所有合同号码,并为所有父母和孩子提供相同的列。
----------------------------
¦ Contract ¦
¦--------------¦------------¦
¦ ID_CONTRACT ¦ ID_EMPLOYEE¦
¦--------------¦------------¦
¦ 1 ¦ 1 ¦
¦--------------¦------------¦
¦ 2 ¦ 4 ¦
¦--------------¦------------¦
¦ 3 ¦ 6 ¦
¦--------------¦------------¦
¦ 4 ¦ 7 ¦
¦--------------¦------------¦
¦ 5 ¦ 12 ¦
¦--------------¦------------¦
¦ 6 ¦ 11 ¦
¦--------------¦------------¦
----------------------------
¦ Employee ¦
¦--------------¦------------¦
¦ ID_EMPLOYEE ¦ ID_MANAGER ¦
¦--------------¦------------¦
¦ 1 ¦ NULL ¦
¦--------------¦------------¦
¦ 2 ¦ 1 ¦
¦--------------¦------------¦
¦ 3 ¦ 1 ¦
¦--------------¦------------¦
¦ 4 ¦ NULL ¦
¦--------------¦------------¦
¦ 5 ¦ NULL ¦
¦--------------¦------------¦
¦ 6 ¦ NULL ¦
¦--------------¦------------¦
¦ 7 ¦ 5 ¦
¦--------------¦------------¦
¦ 8 ¦ NULL ¦
¦--------------¦------------¦
¦ 9 ¦ 5 ¦
¦--------------¦------------¦
¦ 10 ¦ 5 ¦
¦--------------¦------------¦
¦ 11 ¦ NULL ¦
¦--------------¦------------¦
¦ 12 ¦ NULL ¦
¦--------------¦------------¦
我的代码是:
drop table #cnt
select DISTINCT
cnt.ID_CONTRACT,
emp.ID_EMPLOYEE,
emp.ID_MANAGER
into #cnt
from
contract cnt (NOLOCK)
inner join
employee emp (NOLOCK) ON cnt.ID_EMPLOYEE = emp.ID_EMPLOYEE
;WITH contactRec AS
(SELECT
cnt.ID_CONTRACT,cnt.ID_EMPLOYEE, cnt.ID_MANAGER
FROM
#cnt cnt
UNION ALL
SELECT
cnt.ID_CONTRACT,emp.ID_EMPLOYEE, emp.ID_MANAGER
FROM
contactRec cnt
Inner join employee emp on emp.ID_MANAGER = cnt.ID_EMPLOYEE
)
select
[ID_CONTRACT]
ID_EMPLOYEE,
ID_MANAGER
from contactRec
答案 0 :(得分:1)
您可以将WHERE子句添加到CTE的递归元素以强制递归停止。您可能还想添加一个" Path"字段,以便您可以识别可能导致无限递归问题的递归循环:
WITH contactRec AS
(SELECT
cnt.ID_CONTRACT,cnt.ID_EMPLOYEE, cnt.ID_MANAGER,
1 a depth, CAST(cnt.ID_Employee + '>' cnt.ID_Manager AS VARCHAR(5000)) as path
FROM
#cnt cnt
UNION ALL
SELECT
cnt.ID_CONTRACT,emp.ID_EMPLOYEE, emp.ID_MANAGER,
depth + 1 as depth, path + '>' + emp.ID_Manager as path
FROM
contactRec cnt
Inner join employee emp on emp.ID_MANAGER = cnt.ID_EMPLOYEE
WHERE depth <= 20 /*end recursion at 20 cycles*/
)
select
[ID_CONTRACT]
ID_EMPLOYEE,
ID_MANAGER,
depth,
path
from contactRec;
现在它会在20个周期内死亡,你将有一个深度和路径指示器,以帮助提供有关你为什么处于无限循环的线索。
答案 1 :(得分:0)
我无法使用您提供的架构和数据生成maxrecursion错误。但是,我注意到有一件事可能会导致您的递归问题。递归cte的一般形式是:
with cte as (
«base case»
UNION ALL
«recursive query»
)
select *
from cte
(顺便说一句,你已经得到了;我只是想在我的观察中引用上述内容)。在您的基本情况下,您选择所有员工。通常做的是选择顶级或底级员工,然后当你递归时,你可以沿着层次结构向下或向上(分别)。在您的具体情况下,无论如何,从上到下都是有道理的,因为顶级员工很容易识别。具体而言,您的基本案例更改为:
SELECT cnt.ID_CONTRACT ,
cnt.ID_EMPLOYEE ,
cnt.ID_MANAGER
FROM #cnt cnt
到
SELECT cnt.ID_CONTRACT ,
cnt.ID_EMPLOYEE ,
cnt.ID_MANAGER
FROM #cnt cnt
WHERE ID_MANAGER IS NULL
但即使这样也无法解释为什么你会达到递归限制。你确定你的数据是非循环的(也就是说,你没有像1→2→1那样的东西)?