sachsenhessi

MS-SQL T-SQL: verschachtelte Cursor

Hallo @all,
ich brauche mal wieder das Schwarmwissen, da ich den Wald vor lauter Bäumen, und so...
Ausgang: MS-SQLServer-Express V 11.00.7507
Problem:
Ich habe einen Cursor <curAuftrag1> (Forward Only)
Dieser wird durchlaufen und mit jeder "Runde" wird ein zweiter Cursor <curAdressen> erstellt (Forwar Only).
Dieser wird ebenfalls durchlaufen und jeder Datensatz von <curAdressen> dann per INSERT an die Tabelle <Adressdaten> angehangen.
Beispiel:
CREATE PROCEDURE [dbo].[uspCheckAdressenGewicht]
	@Produktionsvariante int,
	@Ausgabe varchar(25)
AS
BEGIN
	        SET NOCOUNT ON;
		DECLARE @AuftragsDetailId BIGINT
		DECLARE @VerlagsID INT
		DECLARE @EinzelGewicht INT

		DECLARE @AdressID BIGINT
		DECLARE @HeftAnzahl INT
		DECLARE @LKZ NVARCHAR(3)
		
    	        DECLARE curAuftrag CURSOR FORWARD_ONLY
		     FOR
			    SELECT AuftragsDetailId, VerlagsID, EinzelGewicht 
				   FROM AuftragsDetail 
				   WHERE ProduktionsVariantenid=@Produktionsvariante AND Ausgabe=@Ausgabe
		OPEN curAuftrag
		FETCH NEXT FROM curAuftrag  INTO @AuftragsDetailId, @VerlagsID, @EinzelGewicht		
		WHILE @@FETCH_STATUS = 0
		BEGIN 
			-- Für jede AuftragsID für die Ausgabe die Adressen zu den Adressen ermitteln
			DECLARE curAdressen CURSOR FORWARD_ONLY
				FOR
					SELECT Counter AS AdressID, HeftAnzahl, LKZ
						FROM Adressdaten 
						WHERE (AusgabeID = @AuftragsDetailId) 
                                                             AND (LKZ IN (SELECT LKZ FROM [dbo].[GewichtsGrenzeVersandFuerLKZ]));
			OPEN curAdressen
			FETCH NEXT FROM curAdressen  INTO @AdressID, @HeftAnzahl, @LKZ
			WHILE  @@FETCH_STATUS = 0
			      BEGIN 
				     --- Hier steht dann das INSERT-Statement in die Tabelle <Adressdaten>
			       END  -- Durch alle Adressen itterieren
                       CLOSE curAdressen
		       DEALLOCATE curAdressen
		END -- Durch alle AuftragsID itterieren
		CLOSE curAuftrag
		DEALLOCATE curAuftrag
END
Ich weis, dass eines der Probleme im <@@Fetch_Status> liegt.
Wie kann ich diese "Verschachtelung" lösen ?
Danke schon mal im Voraus😊
Auf Facebook teilen
Auf X (Twitter) teilen
Auf Reddit teilen
Auf Linkedin teilen

Content-ID: 673030

Url: https://administrator.de/forum/ms-sql-t-sql-verschachtelte-cursor-673030.html

Ausgedruckt am: 27.05.2025 um 18:05 Uhr

ukulele-7
ukulele-7 26.05.2025 um 11:14:23 Uhr
Goto Top
Kannst du mal die Probleme benennen? Was geht und was geht nicht und wie äußert sich das?

Meine Erfahrungen mit Cursorn sind begrenzt weil ich sie fast nie brauche face-smile Wieso arbeitest du in diesem Fall mit einem Cursor, ginge nicht auch einfach ein ordentliches Insert auf Basis eines Selects?
em-pie
em-pie 26.05.2025 aktualisiert um 11:19:33 Uhr
Goto Top
Moin,

Meine Erfahrungen mit Cursorn sind begrenzt weil ich sie fast nie brauche face-smile
Ich ebensowenig

Wieso arbeitest du in diesem Fall mit einem Cursor, ginge nicht auch einfach ein ordentliches Insert auf Basis eines Selects?
Ich hätte bei dem, was ich da so rauslese(n kann) behauptet, dass ein JOIN (ob nun LEFT, RIGHT oder INNER musst du entscheiden) hilft, um dann ein INSERT INTO durchzuführen.

Das dürfte am Ende vermutlich auch performanter sein!?
SachsenHessi
Lösung SachsenHessi 26.05.2025 um 11:22:53 Uhr
Goto Top
Vielen Dank 😊
Ich habe es eben gelöst, weis Gott woran es lag.
ALTER PROCEDURE [dbo].[uspCheckAdressenGewicht]
	@Produktionsvariante int,
	@Ausgabe varchar(25)
AS
BEGIN
	    SET NOCOUNT ON;
		DECLARE @AuftragsDetailId BIGINT
		DECLARE @VerlagsID INT
		DECLARE @EinzelGewicht INT

		DECLARE @AdressID BIGINT
		DECLARE @HeftAnzahl INT
		DECLARE @LKZ NVARCHAR(3)
		
		DECLARE @OuterFetch INT
		DECLARE @InnerFetch INT

    	DECLARE curAuftrag CURSOR FORWARD_ONLY
		     FOR
			    SELECT AuftragsDetailId, VerlagsID, EinzelGewicht 
				   FROM AuftragsDetail 
				   WHERE ProduktionsVariantenid=@Produktionsvariante AND Ausgabe=@Ausgabe
		OPEN curAuftrag
		FETCH NEXT FROM curAuftrag  INTO @AuftragsDetailId, @VerlagsID, @EinzelGewicht	
		SET @OuterFetch = @@FETCH_STATUS
		WHILE @OuterFetch  = 0
		BEGIN 
			-- Für jede AuftragsID für die Ausgabe die Adressen zu den Adressen ermitteln
            PRINT 'ID ---> ' + CAST(@AuftragsDetailId as Varchar(14))  
			DECLARE curAdressen CURSOR FORWARD_ONLY
				FOR
					SELECT Counter AS AdressID, HeftAnzahl, LKZ
						FROM Adressdaten 
						WHERE (AusgabeID = @AuftragsDetailId) 
                                                             AND (LKZ IN (SELECT LKZ FROM [dbo].[GewichtsGrenzeVersandFuerLKZ]));
			OPEN curAdressen
			FETCH NEXT FROM curAdressen  INTO @AdressID, @HeftAnzahl, @LKZ
			SET @InnerFetch = @@FETCH_STATUS
			WHILE  @InnerFetch = 0
			      BEGIN 
				      PRINT '           ---> ' + CAST(@AdressID as Varchar(14))  
					  FETCH NEXT FROM curAdressen  INTO @AdressID, @HeftAnzahl, @LKZ
					  SET @InnerFetch = @@FETCH_STATUS
			       END  -- Durch alle Adressen itterieren
            CLOSE curAdressen
		    DEALLOCATE curAdressen
			FETCH NEXT FROM curAuftrag  INTO @AuftragsDetailId, @VerlagsID, @EinzelGewicht
			SET @OuterFetch = @@FETCH_STATUS	
		END -- Durch alle AuftragsID itterieren
		CLOSE curAuftrag
		DEALLOCATE curAuftrag
END
ukulele-7
ukulele-7 26.05.2025 um 11:36:45 Uhr
Goto Top
Also in deinem ersten Post steht kein FETCH NEXT innerhalb von WHILE BEGIN END, in deinem zweiten ist das enthalten.

Dennoch mein Rat, lieber ein INSERT SELECT verwenden.
Crusher79
Crusher79 26.05.2025 um 12:06:57 Uhr
Goto Top
Zitat von @em-pie:

Ich hätte bei dem, was ich da so rauslese(n kann) behauptet, dass ein JOIN (ob nun LEFT, RIGHT oder INNER musst du entscheiden) hilft, um dann ein INSERT INTO durchzuführen.

Das dürfte am Ende vermutlich auch performanter sein!?

Hatte ich vor langen mal mit Cursorn. Idee war eig. das man es über Systemtabellen o.ä. lauf lässt und dann bestimmte Dinge aulöst. DB Backup geht ja auch.

https://www.mssqltips.com/sqlservertip/1599/cursor-in-sql-server/

Backup. Collation umstellen? Ich weiss nicht mehr wofür ich es damals genommen hab. Idee ist halt wie beim manuellen Prozeß: ich gehen was durch und führe Aktion aus.

INSERT reicht da teils nicht aus. EXEC irgendwas.

Ich weiß nur noch, dass es bei Schleifen Probleme gab. Entweder fehlt eins und ein Element wurde doppel verwurstet. Da gab es auch einen "Fix" um immer unique Ergenisse zu haben.

Lange her bei mir.
Crusher79
Crusher79 26.05.2025 um 12:09:16 Uhr
Goto Top
Zitat von @SachsenHessi:

Vielen Dank 😊
Ich habe es eben gelöst, weis Gott woran es lag.

Manuell oder Debug wenn ich fragen darf? Alte SQL Server war ja easy. Bei den neuen muss man sich ja teils mit Visual Studio verbinden. Ist es ein remote Server, muss der Server Dienst unter dem jeweiigen User laufen, damit man Werte erhält. Hatte ich bis dato nur einmal gemacht.

Bei lokaler Installatioin fällt das ja weg. Normal hätte dir doch dann das Studio den Fehler anzeigen müssen - Thrown Exception....