Vinzenz Mai: stored procedures -> reuckgabewert

Beitrag lesen

Hallo Ingrid,

vieles stimmte, aber leider nicht alles. Jetzt getestet:

warum ich keine funktion nehme, kann ich dir ehrlich gesagt nicht sagen. ich nehme an, dass dies dort auch nicht besser zu loesen ist, oder?

wie dedlfix bereits schrieb, ist GROUP_CONCAT() die einfachere, elegantere und vermutlich schnellere Lösung :-) Du hast bei Deiner Funktion noch einiges nicht beachtet:

  
-- idList gefällt mir besser, es braucht auch nicht maskiert zu werden  
CREATE PROCEDURE ein_test(OUT idList text)  
BEGIN  
    DECLARE done BOOLEAN DEFAULT FALSE;  
    DECLARE res INT;  
    DECLARE cur CURSOR FOR SELECT s.id FROM elv_season s;  
    -- NOT FOUND ist lesbarer als SQLSTATE '02000'  
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;  
  
    --  Welchen Wert hat die Variable idList?  
    --  Antwort: da nicht initialisiert, hat sie den Wert NULL  
    SET idList = '';  
  
    OPEN cur;  
    WHILE NOT done DO  
        FETCH cur INTO res;  
        -- Zweiter Fehler:  
        -- Wenn done wahr wird, darf die nächste Anweisung nicht  
        -- ausgeführt werden.  
        [link:http://dev.mysql.com/doc/refman/5.1/en/if-statement.html@title=IF] NOT done THEN  
            -- CONCAT(irgendwas, NULL) ergibt NULL.  
            -- Wegen der fehlenden Initialisierung gibt es Deinen NULL-Wert.  
            -- Dritter Fehler:  
            -- Im ersten Schleifendurchlauf ist idList der Leerstring,  
            -- diesem wird zunächst ein Komma, dann der erste Wert angefügt  
            -- Um dies zu verhindern, muss geprüft werden, ob es sich um  
            -- den ersten Durchlauf handelt.  
            IF idList = '' THEN  
                SET idList = res;  
            ELSE  
                SET idList = CONCAT(idList, ',', res);  
            END IF;  
        END IF  
    END WHILE;  
  
    CLOSE cur;  
END
  
CREATE PROCEDURE ein_test(OUT idList text)  
BEGIN  
    DECLARE done BOOLEAN DEFAULT FALSE;  
    DECLARE res INT;  
    DECLARE cur CURSOR FOR SELECT s.id FROM elv_season s;  
    -- NOT FOUND ist lesbarer als SQLSTATE '02000'  
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;  
  
    --  Welchen Wert hat die Variable idList?  
    --  Antwort: da nicht initialisiert, hat sie den Wert NULL  
    --  Dies können wir auch nutzen, um den ersten Durchlauf zu erkennen:  
  
    OPEN cur;  
    WHILE NOT done DO  
        FETCH cur INTO res;  
        IF NOT done THEN  
            IF idList IS NULL THEN  
                SET idList = res;  
            ELSE  
                SET idList = CONCAT(idList, ',', res);  
            END IF;  
        END IF  
    END WHILE;  
  
    CLOSE cur;  
END

Schreiben wir es um mit LOOP und nutzen die Funktion COALESCE(), um den ersten Durchlauf abzufangen:

CREATE PROCEDURE ein_test(OUT idList text)  
BEGIN  
    DECLARE done BOOLEAN DEFAULT FALSE;  
    DECLARE res INT;  
    DECLARE cur CURSOR FOR SELECT s.id FROM elv_season s;  
    DECLARE CONTINUE HANDLER FOR [link:http://dev.mysql.com/doc/refman/5.1/en/declare-handler.html@title=NOT FOUND] SET done = TRUE;  
  
    OPEN cur;  
    myLoop: [link:http://dev.mysql.com/doc/refman/5.1/en/loop-statement.html@title=LOOP]  
        FETCH cur INTO res;  
        [link:http://dev.mysql.com/doc/refman/5.1/en/if-statement.html@title=IF] done THEN  
            CLOSE cur;  
            [link:http://dev.mysql.com/doc/refman/5.0/en/leave-statement.html@title=LEAVE] myLoop;  
        END IF  
  
        SET idList = [link:http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce@title=COALESCE](CONCAT(idList, ',', res), res);  
  
    END LOOP;  
  
    CLOSE cur;  
END

Und alles in allem liefert dies nichts anderes als ein einfaches

SELECT [link:http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat@title=GROUP_CONCAT](id) FROM elv_season

Freundliche Grüße

Vinzenz