繁体   English   中英

如何在递归 Function 中使用循环中的#tmp 表

[英]How to use #tmp Table in Loop in Recursive Function

我正在尝试创建一个循环,当给定零件 ID 时,它将搜索装配零件表并将所有零件分解成一个大列表。

它需要递归,因为第 123 部分可能有第 1、2、3、4、5 部分,第 4 和第 5 部分也是装配项。 我以为我想出了一些非常好的东西,并且很容易返回每个项目的零件 ID 和零件级别。 然后我发现我不能使用临时表,所以它把我的循环打断了。

我可以用什么代替临时表在这里给我相同的 function?

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


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

    SET @level += 1

    SELECT [Comp_Part_ID] AS [PID], @level AS [level]
    INTO #chkParts
    FROM [assemblies]
    WHERE [Assy_PID] = @source_part_id

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

    RETURN
END

以下是一些示例数据:

CREATE TABLE [Assemblies] (
  [PartID] int,
  [Comp_PartID] int
  )
  
  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)

如果我输入SELECT * FROM [fn_getParts](1,0)我会期望以下内容:

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

通过将内联表值 Function 包裹在递归 CTE 周围,可以稍微简化代码,例如:

create function dbo.fn_getParts (
    @source_part_id int
)
returns table as return (
    with PartsHierarchy as (
      select @source_part_id as part, 0 as level
      union all
      select Comp_PartID, 1 + level
      from Assemblies
      join PartsHierarchy on part = PartID
    )
    select part, level
    from PartsHierarchy
);

然后,为不同的零件号调用它......

select * from dbo.fn_getParts(1);
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
select * from dbo.fn_getParts(10);
part level
---- -----
  10    0
  11    1
  23    1
  24    1
  31    1
  24    2
  23    2
select * from dbo.fn_getParts(11);
part level
---- -----
  11    0
  24    1
  23    1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM