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