2013-11-01 2 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 rate를 증가시키지 않았기 때문에 한계에 상관없이 (무한히 0을 시도했습니다. 무한 루프를 제외하고는 모두 무제한입니다. 몇 분 전에 살해]) –

답변

0

통해 @HABO, 나는 쿼리의 깊이에 제한을 추가 할 수있었습니다. 이렇게하면 더 잘 실행하고 디버깅 할 수 있습니다.

이 경우 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