Ich habe eine gespeicherte Prozedur geschrieben, die ein Elternteil, gehen Sie durch die Stücklisten Datensätze für diesen Teil und konditionieren passender Kind-Datensätze (dh die Teile, die enthalten sind) in der Stückliste dieses Teils), aber nur Kind-Datensätze, die bestimmte Kriterien erfüllen (unter Verwendung unserer Namenskonvention, alles beginnend mit '.', 'E' oder 'ZG').Verwenden Sie eine Variable im Cursor SELECT-Anweisung
Ich habe den SP erstellt und es funktioniert wunderbar, aber nur, wenn ich eine [optional] Elternteilenummer übergeben. Ich muss diesen SP für alle Teile ausführen, also dachte ich, den SP innerhalb eines Cursors auszuführen und im nächsten Teil weiterzumachen, bis keine mehr zu bearbeiten sind. Ich kann nicht herausfinden, wie das geht, oder wenn es sogar möglich ist, weil in der SELECT-Anweisung des Cursors (in der ich den gespeicherten Prozedurcode verwende) ich eine Variable übergeben muss, damit es funktioniert. Hier
ist der Code für die gespeicherte Prozedur:
CREATE PROCEDURE dbo.usp_BuildBOMLit
@item_no CHAR(8) = NULL
AS
BEGIN
WITH CTE AS (
SELECT DISTINCT
LTRIM(RTRIM(lvl1.item_no)) as item_no, LTRIM(RTRIM(lvl1.comp_item_no)) as comp_item_no,
CASE
WHEN LTRIM(RTRIM(lvl1.comp_item_no)) LIKE '.%'
THEN
LTRIM(RTRIM(lvl1.comp_item_no))
WHEN LTRIM(RTRIM(lvl1.comp_item_no)) LIKE 'E%'
THEN
(SELECT TOP 1 LTRIM(RTRIM(comp_item_no)) FROM bmprdstr_sql WHERE LTRIM(RTRIM(item_no))=LTRIM(RTRIM(lvl1.comp_item_no)) AND LTRIM(RTRIM(comp_item_no)) LIKE '.%')
WHEN LTRIM(RTRIM(lvl1.comp_item_no)) LIKE 'ZG%'
THEN
(SELECT TOP 1 LTRIM(RTRIM(comp_item_no)) FROM bmprdstr_sql WHERE LTRIM(RTRIM(item_no))=LTRIM(RTRIM(lvl1.comp_item_no)) AND LTRIM(RTRIM(comp_item_no)) LIKE '.%')
ELSE
NULL
END as lvl_2_comp_item_no
FROM
bmprdstr_sql as lvl1
LEFT JOIN bmprdstr_sql lvl2 ON lvl1.comp_item_no=lvl2.item_no
WHERE
(lvl1.item_no = @item_no)
AND (lvl1.comp_item_no LIKE '.%' OR lvl1.comp_item_no LIKE 'ZG%' OR lvl1.comp_item_no LIKE 'E%')
)
SELECT DISTINCT
CASE
WHEN LEFT(item_no,1)='.'
THEN STUFF(item_no,1,1,'')
ELSE
item_no
END as item_no,
part_no =
STUFF((SELECT DISTINCT ',' +
CASE
WHEN LEFT(lvl_2_comp_item_no,1)='.'
THEN STUFF(lvl_2_comp_item_no,1,1,'')
ELSE lvl_2_comp_item_no
END
FROM CTE where [email protected]_no FOR XML PATH('')),1,1,'')
FROM
CTE
WHERE
lvl_2_comp_item_no IS NOT NULL AND item_no IS NOT NULL
END
Ausgang ist genau das Format ich brauche:
item_no | part_no
JM9027 | GS10702, LB2391, LB2704, LB2834, LB2896, LB6996
Wenn ich die Cursor zu erstellen, ich bin mit dem gleichen Code in dem SELECT
Anweisung des Cursors, aber wie Sie sehen können, wenn die Eltern erfordern (@itemno
) in übergeben werden Ich habe es vergeblich versucht:
SET NOCOUNT ON;
DECLARE @itemno CHAR(15);
DECLARE @partno VARCHAR(254);
DECLARE @outside_cursor AS CURSOR;
SET @outside_cursor = CURSOR FAST_FORWARD FOR
WITH CTE AS
(SELECT DISTINCT
LTRIM(RTRIM(lvl1.item_no)) AS item_no,
LTRIM(RTRIM(lvl1.comp_item_no)) AS comp_item_no,
CASE
WHEN LTRIM(RTRIM(lvl1.comp_item_no)) LIKE '.%'
THEN LTRIM(RTRIM(lvl1.comp_item_no))
WHEN LTRIM(RTRIM(lvl1.comp_item_no)) LIKE 'E%'
THEN
(SELECT TOP 1
LTRIM(RTRIM(comp_item_no))
FROM
bmprdstr_sql
WHERE
LTRIM(RTRIM(item_no))=LTRIM(RTRIM(lvl1.comp_item_no))
AND LTRIM(RTRIM(comp_item_no)) LIKE '.%'
)
WHEN LTRIM(RTRIM(lvl1.comp_item_no)) LIKE 'ZG%'
THEN
(SELECT TOP 1
LTRIM(RTRIM(comp_item_no))
FROM
bmprdstr_sql
WHERE
LTRIM(RTRIM(item_no))=LTRIM(RTRIM(lvl1.comp_item_no))
AND LTRIM(RTRIM(comp_item_no)) LIKE '.%'
)
ELSE NULL
END AS lvl_2_comp_item_no
FROM
bmprdstr_sql AS lvl1
LEFT JOIN bmprdstr_sql lvl2 ON lvl1.comp_item_no=lvl2.item_no
WHERE
(lvl1.item_no = @itemno) -- <-- problem
AND (lvl1.comp_item_no LIKE '.%' OR lvl1.comp_item_no LIKE 'ZG%'
OR lvl1.comp_item_no LIKE 'E%')
)
SELECT DISTINCT
CASE
WHEN LEFT(item_no,1)='.'
THEN STUFF(item_no,1,1,'')
ELSE item_no
END AS item_no,
part_no =
STUFF(
(SELECT DISTINCT ',' +
CASE
WHEN LEFT(lvl_2_comp_item_no,1)='.'
THEN STUFF(lvl_2_comp_item_no,1,1,'')
ELSE lvl_2_comp_item_no
END
FROM
CTE
WHERE
[email protected] FOR XML PATH('')),1,1,'')
--^problem
FROM
CTE
WHERE
lvl_2_comp_item_no IS NOT NULL
AND item_no IS NOT NULL
OPEN @outside_cursor;
FETCH NEXT FROM @outside_cursor INTO @itemno, @partno;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO items_parts (item_no, part_no)
VALUES (@itemno, @partno)
FETCH NEXT FROM @outside_cursor INTO @itemno, @partno
END
CLOSE @outside_cursor
DEALLOCATE @outside_cursor
Irgendwelche Ratschläge, wie dies erreicht werden kann?
Nicht sicher, warum Sie einen Cursor zum Einfügen von Daten verwenden. Ich habe nicht versucht, diese große Abfrage zu analysieren, um wirklich zu sehen, was es tut, aber das kann als eine einzelne Menge aufgeschrieben werden. Hier ist ein großartiger Ort, um anzufangen. http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –
@SeanLange Jede Frage über SQL-Cursor endet mit diesem Kommentar in einer Form oder ein anderes. Ich habe versucht, einen Set-basierten Ansatz zu verwenden, bevor ich zum Cursor ging. – SpaceAge
Das liegt daran, dass fast jeder Cursor mit einem Set-basierten Ansatz anstelle von RBAR gelöst werden kann. –