我正在尝试使用带有光标的存储过程或函数来减少重复 SQL "code",我正在寻找 advice/assistance

I'm trying to use a stored procedure or function with cursor to cut down on repeated SQL "code", and I'm looking for advice/assistance

这有点摸不着头脑,但我有一组有效的游标,它们基本上从特定的 parentId(或可能是多个)向下钻取到它的每个子代、它的子代的子代,以及child's children children 实质上达到层次结构的底部 - 其分类为“Base Builds”。

现在我已经有了实际的逻辑工作,我正在以 C# .NET 程序员(而不是 SQL 方面特别熟练的人)的身份看待这个混乱,并且发现自己想知道我是否可以减少每个将这些游标合并到一个函数或存储过程中,这样它更容易重用而且不那么难看。

我想指出,我通过研究游标知道游标是邪恶的,应该避免,但我的经理坚决反对我在 SQL 中构建它,并建议我使用游标来这样做- 我会说,如果您碰巧知道解决相同问题的更好方法,我愿意听取游标以外的建议。

DECLARE @parentId varchar(10) = '150192'
DECLARE @compId varchar(10)
DECLARE @classification varchar(50)

DECLARE cursor_one CURSOR FOR 
    SELECT DISTINCT PST.PST_ParentItemID ,PST.PST_CompItemID, IMA.IMA_Classification FROM PST 
    INNER JOIN IMA ON PST.PST_CompItemID = IMA.IMA_ItemID  
    WHERE PST_CompItemID = @parentId --IN ('150192', '150222', '150177', '150176', '150241', '150233', '150203', '150206')
    AND PST_ParentItemID NOT LIKE 'Q%'

OPEN cursor_one
FETCH NEXT FROM cursor_one INTO @parentId, @compId, @classification

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT 'Cursor1: ' + @parentId + ' - ' + @compId + ' - ' + @classification
     
    DECLARE cursor_two CURSOR FOR
        SELECT DISTINCT PST.PST_ParentItemID ,PST.PST_CompItemID, IMA.IMA_Classification FROM PST 
        INNER JOIN IMA ON PST.PST_CompItemID = IMA.IMA_ItemID  
        WHERE PST_CompItemID = @parentId
        AND PST_ParentItemID NOT LIKE 'Q%'

    OPEN cursor_two
    FETCH NEXT FROM cursor_two INTO @parentId, @compId, @classification

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT 'Cursor2: ' + @parentId + ' - ' + @compId + ' - ' + @classification
----------------------------
        
        DECLARE cursor_three CURSOR FOR
            SELECT DISTINCT PST.PST_ParentItemID ,PST.PST_CompItemID, IMA.IMA_Classification FROM PST 
            INNER JOIN IMA ON PST.PST_CompItemID = IMA.IMA_ItemID  
            WHERE PST_CompItemID = @parentId
            AND PST_ParentItemID NOT LIKE 'Q%'

        OPEN cursor_three
        FETCH NEXT FROM cursor_three INTO @parentId, @compId, @classification

        WHILE @@FETCH_STATUS = 0
        BEGIN
            PRINT 'Cursor3: ' + @parentId + ' - ' + @compId + ' - ' + @classification
---------------------------

            DECLARE cursor_four CURSOR FOR
                SELECT DISTINCT PST.PST_ParentItemID ,PST.PST_CompItemID, IMA.IMA_Classification FROM PST 
                INNER JOIN IMA ON PST.PST_CompItemID = IMA.IMA_ItemID  
                WHERE PST_CompItemID = @parentId
                AND PST_ParentItemID NOT LIKE 'Q%'

            OPEN cursor_four
            FETCH NEXT FROM cursor_four INTO @parentId, @compId, @classification

            WHILE @@FETCH_STATUS = 0
            BEGIN
                PRINT 'Cursor4: ' + @parentId + ' - ' + @compId + ' - ' + @classification
---------------------------

                DECLARE cursor_five CURSOR FOR
                    SELECT DISTINCT PST.PST_ParentItemID ,PST.PST_CompItemID, IMA.IMA_Classification FROM PST 
                    INNER JOIN IMA ON PST.PST_CompItemID = IMA.IMA_ItemID  
                    WHERE PST_CompItemID = @parentId
                    AND PST_ParentItemID NOT LIKE 'Q%'

                OPEN cursor_five
                FETCH NEXT FROM cursor_five INTO @parentId, @compId, @classification

                WHILE @@FETCH_STATUS = 0
                BEGIN
                    PRINT 'Cursor5: ' + @parentId + ' - ' + @compId + ' - ' + @classification
----------------------------

                    DECLARE cursor_six CURSOR FOR
                        SELECT DISTINCT PST.PST_ParentItemID ,PST.PST_CompItemID, IMA.IMA_Classification FROM PST 
                        INNER JOIN IMA ON PST.PST_CompItemID = IMA.IMA_ItemID  
                        WHERE PST_CompItemID = @parentId
                        AND PST_ParentItemID NOT LIKE 'Q%'

                    OPEN cursor_six
                    FETCH NEXT FROM cursor_six INTO @parentId, @compId, @classification

                    WHILE @@FETCH_STATUS = 0
                    BEGIN
                        PRINT 'Cursor6: ' + @parentId + ' - ' + @compId + ' - ' + @classification
                        FETCH NEXT FROM cursor_six INTO @parentId, @compId, @classification
                    END
                    CLOSE cursor_six
                    DEALLOCATE cursor_six

----------------------------
                    FETCH NEXT FROM cursor_five INTO @parentId, @compId, @classification
                END
                CLOSE cursor_five
                DEALLOCATE cursor_five

----------------------------
                FETCH NEXT FROM cursor_three INTO @parentId, @compId, @classification
            END
            CLOSE cursor_four
            DEALLOCATE cursor_four

---------------------------
            FETCH NEXT FROM cursor_three INTO @parentId, @compId, @classification
        END
        CLOSE cursor_three
        DEALLOCATE cursor_three

----------------------------
        FETCH NEXT FROM cursor_two INTO @parentId, @compId, @classification
    END
    CLOSE cursor_two
    DEALLOCATE cursor_two

    BEGIN
        FETCH NEXT FROM cursor_one INTO @parentId, @compId, @classification
    END
END
CLOSE cursor_one
DEALLOCATE cursor_one

为了测试,返回类似这样的输出:

Cursor1: 150193 - 150192 - Packaging
Cursor2: 10971 - 150193 - Packaging
Cursor3: 200871 - 10971 - Fabricated Items
Cursor4: 220011 - 200871 - Base Builds
Cursor4: 200872 - 10971 - Fabricated Items
Cursor4: 200873 - 10971 - Fabricated Items
Cursor4: 200874 - 10971 - Fabricated Items
Cursor4: 200875 - 10971 - Fabricated Items
Cursor4: 200876 - 10971 - Fabricated Items
Cursor4: 200880 - 10971 - Fabricated Items
Cursor4: 200881 - 10971 - Fabricated Items
Cursor4: 200909 - 10971 - Fabricated Items
Cursor4: 200910 - 10971 - Fabricated Items
Cursor4: 200941 - 10971 - Fabricated Items
Cursor4: 200942 - 10971 - Fabricated Items
Cursor4: 200954 - 10971 - Fabricated Items
Cursor4: 200964 - 10971 - Fabricated Items
Cursor5: 220026 - 200964 - Base Builds
Cursor4: 200965 - 10971 - Fabricated Items
Cursor4: 200985 - 10971 - Fabricated Items
Cursor4: 200986 - 10971 - Fabricated Items
Cursor4: 201085 - 10971 - Fabricated Items
Cursor4: 201086 - 10971 - Fabricated Items
Cursor4: 201222 - 10971 - Fabricated Items
Cursor4: 201232 - 10971 - Fabricated Items
Cursor4: 201243 - 10971 - Fabricated Items
Cursor5: 220050 - 201243 - Base Builds
Cursor4: 201314 - 10971 - Fabricated Items
Cursor4: 201359 - 10971 - Fabricated Items
Cursor4: 340088 - 10971 - Fabricated Items
Cursor4: 340089 - 10971 - Fabricated Items
Cursor4: 340090 - 10971 - Fabricated Items
Cursor4: 340093 - 10971 - Fabricated Items
Cursor4: 340095 - 10971 - Fabricated Items
Cursor4: 340100 - 10971 - Fabricated Items
Cursor4: 340103 - 10971 - Fabricated Items
Cursor4: 340107 - 10971 - Fabricated Items
Cursor4: 340132 - 10971 - Fabricated Items
Cursor4: 340135 - 10971 - Fabricated Items
Cursor4: 340152 - 10971 - Fabricated Items
Cursor4: 340173 - 10971 - Fabricated Items
Cursor4: 340179 - 10971 - Fabricated Items
Cursor4: 340237 - 10971 - Fabricated Items
Cursor2: 10979 - 150193 - Packaging
Cursor3: 200877 - 10979 - Fabricated Items
Cursor3: 200878 - 10979 - Fabricated Items
Cursor3: 200919 - 10979 - Fabricated Items
Cursor3: 200920 - 10979 - Fabricated Items
Cursor1: 240044 - 150192 - Packaging
Cursor1: 240063 - 150192 - Packaging
Cursor1: 240071 - 150192 - Packaging
Cursor1: 240085 - 150192 - Packaging
Cursor1: 240108 - 150192 - Packaging
Cursor1: 240118 - 150192 - Packaging
Cursor1: 240120 - 150192 - Packaging
Cursor1: 240158 - 150192 - Packaging
Cursor1: 240176 - 150192 - Packaging
Cursor1: 240224 - 150192 - Packaging
Cursor1: 240283 - 150192 - Packaging
Cursor1: 240436 - 150192 - Packaging
Cursor1: 240470 - 150192 - Packaging
Cursor1: 240504 - 150192 - Packaging
Cursor1: 240522 - 150192 - Packaging
Cursor1: 250008 - 150192 - Packaging
Cursor1: 250009 - 150192 - Packaging
Cursor1: 250010 - 150192 - Packaging

尝试使用递归 CTE(通用 Table 表达式),类似于以下内容...

declare @ParentID varchar(10) = '150192';

with Hierarchy as (
  -- "Root" node(s)
  select distinct 1 as Level, PST.PST_ParentItemID as ParentID, PST.PST_CompItemID as CompID, IMA.IMA_Classification as Classification
  from PST
  inner join IMA on PST.PST_CompItemID = IMA.IMA_ItemID
  where PST_CompItemID = @ParentId
  and PST_ParentItemID not like 'Q%'

  union all

  -- "Child" node(s)
  select 1+Level, PST.PST_ParentItemID, PST.PST_CompItemID, IMA.IMA_Classification
  from Hierarchy
  inner join PST on PST_CompItemID = ParentID and PST_ParentItemID not like 'Q%'
  inner join IMA on PST.PST_CompItemID = IMA.IMA_ItemID
)
select Level, ParentID, CompID, Classification
from Hierarchy

returns 输出类似于以下...

Level ParentID CompID Classification
1 150193 150192 Packaging
1 240044 150192 Packaging
1 240063 150192 Packaging
1 240071 150192 Packaging
1 240085 150192 Packaging
1 240108 150192 Packaging
1 240118 150192 Packaging
1 240120 150192 Packaging
1 240158 150192 Packaging
1 240176 150192 Packaging
1 240224 150192 Packaging
1 240283 150192 Packaging
1 240436 150192 Packaging
1 240470 150192 Packaging
1 240504 150192 Packaging
1 240522 150192 Packaging
1 250008 150192 Packaging
1 250009 150192 Packaging
1 250010 150192 Packaging
2 10971 150193 Packaging
2 10979 150193 Packaging
3 200877 10979 Fabricated Items
3 200878 10979 Fabricated Items
3 200919 10979 Fabricated Items
3 200920 10979 Fabricated Items
3 200871 10971 Fabricated Items

...