2013-11-01 57 views
-1

嗨我得到了最近被一位同事誰是度假修改的存儲過程,我在遞歸SQL的經驗是相當有限的。我目前得到:遞歸存儲過程

最大遞歸100已經完成語句

任何想法之前已經用盡?

ALTER PROCEDURE [dbo].[SP_BOM_GetRawMBOM] 
    @JobNo varchar(20), 
    @ImportNo int = NULL 
AS 
BEGIN 
SET NOCOUNT ON 

IF @ImportNo IS NULL 
     SELECT @ImportNo = MAX(ImportNo) 
     FROM Import 
     WHERE JobNo = @JobNo AND SourceType = 'MBOM' 

--Can't have aggregates in recursive portion of the common table, 
--so get what we need to filter and inner join. 
SELECT Drawing, MAX(ImportNo) AS ImportNo 
INTO #DrawingImportNo 
FROM RawMBOM 
WHERE 
    JobNo = @JobNo AND 
    ImportNo <= @ImportNo AND 
    Drawing NOT LIKE '_3_2_' 
GROUP BY Drawing 

SET NOCOUNT OFF 

;WITH Mbom AS (
    --Top (Skid) Level 
    SELECT 
     S.JobNo, 
     S.ImportNo, 
     CAST('»'+RTRIM(S.Drawing) AS varchar(500)) AS KeyField, 
     S.Drawing AS Skid, 
     S.Drawing, 
     S.Drawing AS PartKey, 
     S.PartNo, 
     S.Description, 
     S.Qty, 
     S.PartSize, 
     S.PartLength, 
     S.Material, 
     S.CutLength, 
     S.Ported, 
     S.Rev, 
     S.IsSub 
    FROM RawMbom S 
     INNER JOIN #DrawingImportNo D ON D.Drawing = S.Drawing AND D.ImportNo = S.ImportNo 
    WHERE 
     JobNo = @JobNo AND 
     RTRIM(PartKey) = '' AND 
     NOT EXISTS (SELECT PartKey FROM RawMBOM WHERE JobNo = @JobNo AND ImportNo <= @ImportNo AND PartKey = S.Drawing) 
    UNION ALL 
    --Recursive parts and subassemblies 
    SELECT 
     R.JobNo, 
     R.ImportNo, 
     CAST(RTRIM(U.KeyField)+'»'+R.PartKey AS varchar(500)) AS KeyField, 
     U.Skid, 
     R.Drawing, 
     R.PartKey, 
     R.PartNo, 
     R.Description, 
     U.Qty * R.Qty AS Qty, 
     R.PartSize, 
     R.PartLength, 
     R.Material, 
     R.CutLength, 
     R.Ported, 
     R.Rev, 
     R.IsSub 
    FROM RawMbom R 
     INNER JOIN Mbom AS U ON R.Drawing = U.PartKey 
     INNER JOIN #DrawingImportNo D ON D.Drawing = R.Drawing AND D.ImportNo = R.ImportNo 
) 
SELECT * FROM Mbom 
WHERE 
    RTRIM(PartKey) <> '' AND IsSub = 0 AND --Remove assemblies from the mix 
    UPPER(LEFT(PartNo,3)) <> 'REF' AND --Don't pass because it is on ELT or EBOM 
    (
     (DATALENGTH(RTRIM(PartSize))>0) OR 
     (DATALENGTH(RTRIM(PartLength))>0) OR 
     (DATALENGTH(RTRIM(Material))>0) OR 
     (DATALENGTH(RTRIM(PartNo))>0) 
    ) -- Don't pass on blank parts. 

DROP TABLE #DrawingImportNo 
END 
+0

我試圖增加MAXRECURSION,但它肯定在某種無限循環。 –

+0

請分享您的研究和嘗試解決方案的更多細節,並告訴我們爲什麼他們不工作。 – Jeroen

+0

Jeroen,增加maxrecursion率沒有工作,因爲它陷在一個無限循環,所以無論限制(我試圖0 [無限]等人無濟於事,他們都達成了[除了無限,我等待殺人前幾分鐘]) –

回答

0

通過@HABO,我能夠添加限制到查詢的深度。這將允許我更正確地運行和調試它。

爲此,哈勃已超過here答案。

對於那些懶得點擊過,細節是您添加的深度或水平列的主要功能和遞歸部分加一。 新的查詢,亮點:

BEGIN 

SET NOCOUNT ON 

IF @ImportNo IS NULL SELECT @ImportNo = MAX(ImportNo) FROM Import WHERE JobNo = @JobNo AND SourceType = 'MBOM' 

--Can't have aggregates in recursive portion of the common table, 
--so get what we need to filter and inner join. 
SELECT Drawing, MAX(ImportNo) AS ImportNo 
INTO #DrawingImportNo 
FROM RawMBOM 
WHERE 
    JobNo = @JobNo AND 
    ImportNo <= @ImportNo AND 
    -- Work instruction P.25 x3x2x is a drawing for a prefabricated vessel. 
    --Parts do not get processed in the BOM because parts come as 
    --part of the vessel. Example - Site Glasses 
    Drawing NOT LIKE '_3_2_' 
GROUP BY Drawing 

SET NOCOUNT OFF 

;WITH Mbom AS (
    --Top (Skid) Level 
    SELECT 
     S.JobNo, 
     S.ImportNo, 
     CAST('»'+RTRIM(S.Drawing) AS varchar(500)) AS KeyField, 
     S.Drawing AS Skid, 
     S.Drawing, 
     S.Drawing AS PartKey, 
     S.PartNo, 
     S.Description, 
     S.Qty, 
     S.PartSize, 
     S.PartLength, 
     S.Material, 
     S.CutLength, 
     S.Ported, 
     S.Rev, 
     S.IsSub 
     ,1 Depth 
    FROM RawMbom S 
     INNER JOIN #DrawingImportNo D ON D.Drawing = S.Drawing AND D.ImportNo = S.ImportNo 
    WHERE 
     JobNo = @JobNo AND 
     RTRIM(PartKey) = '' AND 
     NOT EXISTS (SELECT PartKey FROM RawMBOM WHERE JobNo = @JobNo AND ImportNo <= @ImportNo AND PartKey = S.Drawing) 
    UNION ALL 
    --Recursive parts and subassemblies 
    SELECT 
     R.JobNo, 
     R.ImportNo, 
     CAST(RTRIM(U.KeyField)+'»'+R.PartKey AS varchar(500)) AS KeyField, 
     U.Skid, 
     R.Drawing, 
     R.PartKey, 
     R.PartNo, 
     R.Description, 
     U.Qty * R.Qty AS Qty, 
     R.PartSize, 
     R.PartLength, 
     R.Material, 
     R.CutLength, 
     R.Ported, 
     R.Rev, 
     R.IsSub 
     ,Depth + 1 
    FROM RawMbom R 
     INNER JOIN Mbom AS U ON R.Drawing = U.PartKey 
     INNER JOIN #DrawingImportNo D ON D.Drawing = R.Drawing AND D.ImportNo = R.ImportNo 
    WHERE Depth < 10 
) 
SELECT * FROM Mbom 
WHERE 
    RTRIM(PartKey) <> '' AND IsSub = 0 AND --Remove assemblies from the mix 
    UPPER(LEFT(PartNo,3)) <> 'REF' AND --Don't pass because it is on ELT or EBOM 
    (
     (DATALENGTH(RTRIM(PartSize))>0) OR 
     (DATALENGTH(RTRIM(PartLength))>0) OR 
     (DATALENGTH(RTRIM(Material))>0) OR 
     (DATALENGTH(RTRIM(PartNo))>0) 
    ) -- Don't pass on blank parts. 

DROP TABLE #DrawingImportNo 
END