Benutzer mit den meisten Antworten
Problem mit Cursor und Funktion mit Cursor

Frage
-
Hallo,
ich erstelle eine temporäre Tabelle, in welcher anschließend Werte mittels eines Cursors umgeschrieben werden. Dieser Cursor wird geschlossen und deallokiert. In der weiteren Abfolge der Statements rufe ich über die gleiche Datenverbindung eine Scalar-valued Function auf, in welcher ebenfalls ein Cursor ausgeführt wird und die einen Integer-Wert returnieren soll. Dieser zielt auf eine völlig andere, statische Tabelle in der DB und wird ebenfalls wieder geschlossen und deallokiert.
Mein Problem ist jetzt, das die Function solange einwandfrei arbeitet und korrekte Werte zurückgibt, bis der Cursor der temporären Tabelle ausgeführt wurde. Danach gibt die Function nur noch 0 zurück. Wie kann das zusammenhängen?
Für Eure Tipps dankend,
Klaus
No Brain - No Pain
Antworten
-
Hallo Klaus,
Du verlässt die Funktion ohne de Cursor zu schliessen:
-- springt raus... RETURN @t -- kommt nicht mehr zur Ausführung CLOSE cr_span DEALLOCATE cr_span;
Der Geschwindigkeit zu liebe solltest Du solche Schleifen mit BREAK verlassen, wenn Du einen Treffer hattest:
BEGIN SET @t = 1; -- Schleife verlassen BREAK; END
Soweit der Fehler.
Wobei man das Ganze Cursor-Frei schreiben können sollte:
IF EXISTS(SELECT * FROM WHISTORY WHERE EKEY = @ekey AND dtGueltigAB IS NOT NULL AND ((@ps <= dtGueltigAB AND @pe <= dtGueltigBis AND @pe >= dtGueltigAB) OR (@ps >= dtGueltigAB AND @pe <= dtGueltigBis) OR (@ps >= dtGueltigAB AND @ps <= dtGueltigBis AND @pe >= dtGueltigBis)) OR (@ps <= dtGueltigAB AND @pe >= dtGueltigBis) RETURN 1; RETURN 0;
Gruß Elmar
- Bearbeitet Elmar BoyeEditor Dienstag, 2. April 2013 05:47
- Als Antwort vorgeschlagen Ionut DumaModerator Dienstag, 2. April 2013 08:42
- Als Antwort markiert Klaus Mayer Dienstag, 2. April 2013 18:14
Alle Antworten
-
Ich versuch mal, Snippets zu bauen :-)
Hier der Cursor, welcher die Temp - Tabelle beackert:
DECLARE @ID INT DECLARE @LASTDATE DATETIME DECLARE @ACTDATE DATETIME DECLARE @STAMP VARCHAR(10) DECLARE @DIFF INT DECLARE @LSTEKEY INT DECLARE @ACTEKEY INT DECLARE @DI INT DECLARE curid CURSOR FOR SELECT TKEY FROM #TEMP SET @DI = DATEDIFF(hour, '1900-01-01 00:00:00', '1900-01-01 2:00:00') OPEN curid FETCH curid INTO @ID WHILE @@FETCH_STATUS = 0 BEGIN SET @LSTEKEY = (SELECT EKEY from #TEMP WHERE TKEY = @ID -1) SET @ACTEKEY = (SELECT EKEY from #TEMP WHERE TKEY = @ID) SET @LASTDATE = (SELECT tEnd from #TEMP WHERE TKEY = @ID -1) SET @STAMP = (SELECT START from #TEMP WHERE TKEY = @ID -1) SET @ACTDATE = (SELECT tStart from #TEMP WHERE TKEY = @ID) SET @DIFF = DATEDIFF(HOUR, '0:00:00', CONVERT(DATETIME,@ACTDATE - @LASTDATE)) IF @DIFF < @DI AND @ACTEKEY = @LSTEKEY UPDATE #TEMP SET Start = @STAMP WHERE TKEY = @ID FETCH curid INTO @ID END CLOSE curid DEALLOCATE curid;
Und hier die sv-Function:
CREATE FUNCTION IsValid(@ekey Int, @ps DATETIME, @pe DATETIME) RETURNS INT AS BEGIN DECLARE @t INT SET @t = 0 DECLARE @ms DATETIME DECLARE @me DATETIME DECLARE cr_span CURSOR FOR SELECT dtGueltigAb, dtGueltigBis FROM WHISTORY WHERE EKEY = @ekey ORDER BY dtGueltigAb OPEN cr_span WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM cr_span INTO @ms, @me IF @ms IS NOT NULL AND ((@ps <= @ms AND @pe <= @me AND @pe >= @ms) OR (@ps >= @ms AND @pe <= @me) OR (@ps >= @ms AND @ps <= @me AND @pe >= @me)) OR (@ps <= @ms AND @pe >= @me) BEGIN SET @t = 1 END END RETURN @t CLOSE cr_span DEALLOCATE cr_span; END GO
Thx 4 Help!
Klaus
No Brain - No Pain
-
Hallo Klaus,
Du verlässt die Funktion ohne de Cursor zu schliessen:
-- springt raus... RETURN @t -- kommt nicht mehr zur Ausführung CLOSE cr_span DEALLOCATE cr_span;
Der Geschwindigkeit zu liebe solltest Du solche Schleifen mit BREAK verlassen, wenn Du einen Treffer hattest:
BEGIN SET @t = 1; -- Schleife verlassen BREAK; END
Soweit der Fehler.
Wobei man das Ganze Cursor-Frei schreiben können sollte:
IF EXISTS(SELECT * FROM WHISTORY WHERE EKEY = @ekey AND dtGueltigAB IS NOT NULL AND ((@ps <= dtGueltigAB AND @pe <= dtGueltigBis AND @pe >= dtGueltigAB) OR (@ps >= dtGueltigAB AND @pe <= dtGueltigBis) OR (@ps >= dtGueltigAB AND @ps <= dtGueltigBis AND @pe >= dtGueltigBis)) OR (@ps <= dtGueltigAB AND @pe >= dtGueltigBis) RETURN 1; RETURN 0;
Gruß Elmar
- Bearbeitet Elmar BoyeEditor Dienstag, 2. April 2013 05:47
- Als Antwort vorgeschlagen Ionut DumaModerator Dienstag, 2. April 2013 08:42
- Als Antwort markiert Klaus Mayer Dienstag, 2. April 2013 18:14
-
Hallo,
hab die Function mit dem Cursor nochmal angepasst und getestet, was aber leider wieder fehlschlug. Warum auch immer, ist egal, der Tipp mit dem Select hat's gebracht :-) Wie so oft, das Ding mit dem Wald und den Bäumen....
Danke Euch vielmals! & schöne Grüße,
Klaus
No Brain - No Pain