none
Problem mit Cursor und Funktion mit Cursor RRS feed

  • 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

    Montag, 1. April 2013 16:38

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



    Dienstag, 2. April 2013 05:46
    Beantworter

Alle Antworten

  • Hallo Klaus,

    nur anhand der Beschreibung ist es schwer zu sagen, woran es liegen könnte. Könntest Du evtl. ein gekürztes Code Snipplets der relevanten Teile posten?


    Olaf Helper

    Blog Xing

    Montag, 1. April 2013 16:57
  • 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

    Montag, 1. April 2013 17:05
  • 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



    Dienstag, 2. April 2013 05:46
    Beantworter
  • 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

    Dienstag, 2. April 2013 18:16