2017-09-14 5 views
0

再帰的クエリがあります。私は声明 完了前に枯渇したX再帰的ループの後にクエリを停止

最大再帰100の代わりに戻って、データベースからいくつかの結果を取得したい無限ループがある場合にのみ、クエリは、ほとんどの場合で動作します。

クエリは次のようになります。だから私は、私は上記の問題を解決し、データバックのいくつかのレベルを与えることができるようにクエリを変更したい

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サーバーの再帰クエリで可能ですか?

+0

この行の後にOPTION(MAXRECURSION 2)を使うことができます。SELECT distinct * FROM bom –

+1

@FadySaadそれは何もしないで、エラーメッセージに '100'の代わりに' 2'と言うだけです。 – Siyual

答えて

3

私はあなたが希望している何をすべきか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 

結果

それを行う必要があり、次のような
Date  Level 
2017-09-14 1 
2017-09-15 2 
2017-09-16 3 
2017-09-17 4 
2017-09-18 5 
+0

良い答え。私はOPがそれを理解していないと思うので、私はアンカー、再帰部分、ターミネーターについて説明します。他の人のために[私は何か類似した](https://stackoverflow.com/a/45889108/6167855)。 +1 – scsimon

1

何か:

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に任意のカウンタを置き、その深さに達するとクエリをオフにすることです。

関連する問題