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 中放置一个任意计数器,并在达到该深度时切断查询。