嘿伙计们,我有一个存储过程,最近由一位正在度假的同事修改过,我在递归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 :(得分: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