X 次递归循环后停止查询
Stop query after X recursive loops
我有一个递归查询。该查询在大多数情况下仅在存在无限循环时才有效 我想从数据库而不是
获取一些结果
The maximum recursion 100 has been exhausted before statement
completion.
查询如下:
WITH bom ( [id],[parentNumber],[warehouse],[sequenceNumber]
,[childNumber],[childDescription],[qtyRequired],[childItemClass]
,[childItemType],[scrapFactor],[bubbleNumber] ,[operationNumber]
,[effectivityDate],[discontinuityDate],[companyID]) AS (
select * from [products].[BillOfMaterial] where parentNumber IN ('XXXXXXXXXX')
and companyID = '0'UNION ALL
select c.* from bom b INNER JOIN [products].[BillOfMaterial] c on b.childNumber = c.parentNumber and c.companyID = '0')
SELECT distinct * FROM bom
所以我想更改查询,以便我可以解决上面的问题并返回某些级别的数据。通常这棵树不会超过 5 层。
这在 Sql 服务器递归查询中是否可行?
我不认为有一个 OPTION
可以做你想做的事,但你可以创建一个变量来保存你希望递归发生的最大次数,并在查询:
Declare @MaxLevel Int = 5;
With bom (id, parentNumber, warehouse, sequenceNumber, childNumber, childDescription, qtyRequired, childItemClass, childItemType, scrapFactor, bubbleNumber,
operationNumber, effectivityDate, discontinuityDate, companyID, Level
)
As (Select *,
1 As Level
From products.BillOfMaterial
Where parentNumber In ( 'XXXXXXXXXX' )
And companyID = '0'
Union All
Select c.*,
Level + 1 As Level
From bom b
Inner Join products.BillOfMaterial c
On b.childNumber = c.parentNumber
And c.companyID = '0'
Where Level < @MaxLevel
)
Select Distinct *
From bom;
这是一个带日期的工作示例:
Declare @MaxLevel Int = 5;
;With Cte As
(
Select Convert(Date, GetDate()) As Date,
1 As Level
Union All
Select DateAdd(Day, 1, Date) As Date,
Level + 1 As Level
From Cte
Where Level < @MaxLevel
)
Select *
From Cte
Results
Date Level
2017-09-14 1
2017-09-15 2
2017-09-16 3
2017-09-17 4
2017-09-18 5
像下面这样的事情应该做:
WITH bom ( [id],[parentNumber],[warehouse],[sequenceNumber]
,[childNumber],[childDescription],[qtyRequired],[childItemClass]
,[childItemType],[scrapFactor],[bubbleNumber] ,[operationNumber]
,[effectivityDate],[discontinuityDate],[companyID])
AS (
select *, 1 as Depth
from [products].[BillOfMaterial]
where parentNumber IN ('XXXXXXXXXX')
and companyID = '0'
union all select c.*, b.Depth + 1 as Depth
from bom b
INNER JOIN [products].[BillOfMaterial] c
on b.childNumber = c.parentNumber
and c.companyID = '0'
--where b.Depth < xx
)
SELECT distinct * FROM bom
--where Depth < xx
我没有测试过这个精确的代码,我不确定应该使用哪个 where
子句,但我以前做过这样的查询。这个想法是在跟踪深度 xx 中放置一个任意计数器,并在达到该深度时切断查询。
我有一个递归查询。该查询在大多数情况下仅在存在无限循环时才有效 我想从数据库而不是
获取一些结果The maximum recursion 100 has been exhausted before statement completion.
查询如下:
WITH bom ( [id],[parentNumber],[warehouse],[sequenceNumber]
,[childNumber],[childDescription],[qtyRequired],[childItemClass]
,[childItemType],[scrapFactor],[bubbleNumber] ,[operationNumber]
,[effectivityDate],[discontinuityDate],[companyID]) AS (
select * from [products].[BillOfMaterial] where parentNumber IN ('XXXXXXXXXX')
and companyID = '0'UNION ALL
select c.* from bom b INNER JOIN [products].[BillOfMaterial] c on b.childNumber = c.parentNumber and c.companyID = '0')
SELECT distinct * FROM bom
所以我想更改查询,以便我可以解决上面的问题并返回某些级别的数据。通常这棵树不会超过 5 层。
这在 Sql 服务器递归查询中是否可行?
我不认为有一个 OPTION
可以做你想做的事,但你可以创建一个变量来保存你希望递归发生的最大次数,并在查询:
Declare @MaxLevel Int = 5;
With bom (id, parentNumber, warehouse, sequenceNumber, childNumber, childDescription, qtyRequired, childItemClass, childItemType, scrapFactor, bubbleNumber,
operationNumber, effectivityDate, discontinuityDate, companyID, Level
)
As (Select *,
1 As Level
From products.BillOfMaterial
Where parentNumber In ( 'XXXXXXXXXX' )
And companyID = '0'
Union All
Select c.*,
Level + 1 As Level
From bom b
Inner Join products.BillOfMaterial c
On b.childNumber = c.parentNumber
And c.companyID = '0'
Where Level < @MaxLevel
)
Select Distinct *
From bom;
这是一个带日期的工作示例:
Declare @MaxLevel Int = 5;
;With Cte As
(
Select Convert(Date, GetDate()) As Date,
1 As Level
Union All
Select DateAdd(Day, 1, Date) As Date,
Level + 1 As Level
From Cte
Where Level < @MaxLevel
)
Select *
From Cte
Results
Date Level
2017-09-14 1
2017-09-15 2
2017-09-16 3
2017-09-17 4
2017-09-18 5
像下面这样的事情应该做:
WITH bom ( [id],[parentNumber],[warehouse],[sequenceNumber]
,[childNumber],[childDescription],[qtyRequired],[childItemClass]
,[childItemType],[scrapFactor],[bubbleNumber] ,[operationNumber]
,[effectivityDate],[discontinuityDate],[companyID])
AS (
select *, 1 as Depth
from [products].[BillOfMaterial]
where parentNumber IN ('XXXXXXXXXX')
and companyID = '0'
union all select c.*, b.Depth + 1 as Depth
from bom b
INNER JOIN [products].[BillOfMaterial] c
on b.childNumber = c.parentNumber
and c.companyID = '0'
--where b.Depth < xx
)
SELECT distinct * FROM bom
--where Depth < xx
我没有测试过这个精确的代码,我不确定应该使用哪个 where
子句,但我以前做过这样的查询。这个想法是在跟踪深度 xx 中放置一个任意计数器,并在达到该深度时切断查询。