使用 CTE 而不是 Table 递归函数变量

Use CTE Instead of Table Variable for Recursive Function

我正在尝试创建一个循环,当给定零件 ID 时,它将搜索 table 装配零件并将所有零件放入 return table。 IE。我想从单个零件 ID 分解零件。

需要递归,因为第1部分可能有第2、3、4、5部分;第 3 部分是包含第 9、10 部分的装配项;零件 10 是具有零件 11、23、34、31 的装配项;第 11 部分是包含第 23、24 部分的装配项目。

数据库是 SQL 服务器。

我在这里设置了一些样本日期:http://sqlfiddle.com/#!9/f3cc4f

我期待结果:

part, level
1,    0
2,    1
3,    1
4,    1
9,    2
10,   2
11,   3
23,   3
24,   3

下面是我想出的代码。我遇到了最大递归错误,即使样本数据只有几个级别。我的完整数据集不应超过 15 个级别。显然有些地方设置不正确,我认为 CTE 可能会更好。

CREATE FUNCTION [dbo].[fn_getParts] (@source_part_id int, @level int)
RETURNS @parts_list TABLE (
    [part]  int NOT NULL,
    [level] int NOT NULL
)
AS 
BEGIN
    DECLARE
        @max    int = 0,
        @cnt    int = 0,
        @PID    int = 0,
        @Plvl   int = 0,
        @id     int = 0

    DECLARE @chkParts table ([id] int identity(1,1), [PID] int, [level] int)

    INSERT INTO @parts_list VALUES (@source_part_id, @level)

    SET @level += 1

    INSERT INTO @chkParts
        SELECT [Comp_PartID], @level FROM /*visuser.[EN_BOM]*/ [Assemblies] WHERE [PartID] /*[Assembly_Part_ID]*/ = @source_part_id

    SELECT @max = COUNT(*) FROM @chkParts
    WHILE @cnt <= @max
    BEGIN
        SELECT @id = [id], @PID = [PID], @Plvl = [level] FROM @chkParts WHERE [id] = @cnt
        INSERT INTO @parts_list
            SELECT * FROM [fn_getParts](@PID, @Plvl)
        SET @cnt += 1
    END

    RETURN
END

这是示例数据:

CREATE TABLE Assemblies (
  PartID int NOT NULL,
  Comp_PartID int NOT NULL
);
  
INSERT INTO Assemblies VALUES 
  (1, 2),  
  (1, 3),
  (1, 4),
  (1, 5),
  (1, 6),
  (3, 9),
  (3, 10),
  (10, 11),
  (10, 23),
  (10, 24),
  (10, 31),
  (11, 24),
  (11, 23);

以下生成的结果与您描述的逻辑相符,但与您期望的不同。也许您的逻辑需要调整?

declare @source_part_id int = 1, @level int = 0;

with cte (part, [level])
as (
  select @source_part_id part, @level [level]
  union all
  select Comp_PartID, [level]+1
  from Assemblies A
  inner join cte C on C.Part = A.PartID
)
select part, [level]
from cte
order by part, [level];

Returns:

part    level
1       0
2       1
3       1
4       1
5       1
6       1
9       2
10      2
11      3
23      3
24      3
31      3
24      4
23      4