我正在尝试使用带有光标的存储过程或函数来减少重复 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
...
这有点摸不着头脑,但我有一组有效的游标,它们基本上从特定的 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 |
...