Moja struktura tabeli Drzewko jest nastepujaca:
CREATE TABLE `Drzewko` ( `DrzewkoID` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `RodzicID` int(11) UNSIGNED DEFAULT NULL, `LewaStrona` int(11) UNSIGNED DEFAULT NULL, `PrawaStrona` int(11) UNSIGNED DEFAULT NULL, `Nazwa` varchar(200) collate utf8_polish_ci NOT NULL DEFAULT '', `PrzyjaznaNazwa` varchar(200) collate utf8_polish_ci NOT NULL DEFAULT '', `Sciezka` text collate utf8_polish_ci NOT NULL, PRIMARY KEY (`DrzewkoID`), UNIQUE KEY `DrzewkoID` (`DrzewkoID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
Stworzylem soie taka procedure:
CREATE PROCEDURE `przebudujDrzewko`( IN varRodzicID INTEGER ( 11 ) , IN varLewaStrona INTEGER ( 11 )) NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE varDrzewkoID, varPrawaStrona INT; DECLARE varKoniecWynikow TINYINT; DECLARE kursor CURSOR FOR SELECT DrzewkoID FROM Drzewko WHERE RodzicID = varRodzicID; DECLARE CONTINUE HANDLER FOR NOT FOUND SET varKoniecWynikow = 1; SET varPrawaStrona = varLewaStrona + 1; SET varKoniecWynikow = 0; OPEN kursor; WHILE varKoniecWynikow <> 1 DO FETCH kursor INTO varDrzewkoID; CALL przebudujDrzewko(varDrzewkoID, varPrawaStrona); END WHILE; CLOSE kursor; UPDATE Drzewko SET LewaStrona = varLewaStrona, PrawaStrona = varPrawaStrona WHERE DrzewkoID = varRodzicID; END;
...ale... niechce zadzialac. Caly czas mam blad mowiacy o przekroczeniu max ilosci rekursywnych wywolan (mam to ustawione na 50). Drzewko ograniczylem nawet do 2 wpisow! i nadal to samo.
Nie mam pojecia co jest z tym nie tak.
Moze ktos ma pomysl?
----------------------------------------------------[ EDIT ]
OK. Czesciowo rozwiazalem problem. Otoz samo Open cursor nie powoduje, ze wywola sie zdarzenie NOT FOUND jezeli kursor nic nie zawiera. Trzeba dac FETCHa aby takie zdarzenie sie pojawilo i dopiero wewnatrz petli dac IFa, ktory wyjdzie nam z petli.... zamotane, wiem

Tak wyglada poprawiona procedura:
CREATE PROCEDURE `przebudujDrzewko`( IN varRodzicID INTEGER ( 11 ) , IN varLewaStrona INTEGER ( 11 )) NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE varDrzewkoID, varPrawaStrona INT; DECLARE varKoniecWynikow BOOLEAN; DECLARE kursor CURSOR FOR SELECT DrzewkoID FROM Drzewko WHERE RodzicID = varRodzicID; DECLARE CONTINUE HANDLER FOR NOT FOUND SET varKoniecWynikow = TRUE; SET varPrawaStrona = varLewaStrona + 1; OPEN kursor; LOOP1: LOOP FETCH kursor INTO varDrzewkoID; IF varKoniecWynikow = TRUE THEN /*CLOSE kursor;*/ LEAVE LOOP1; END IF; CALL przebudujDrzewko(varDrzewkoID, varPrawaStrona); END LOOP LOOP1; CLOSE kursor; UPDATE Drzewko SET LewaStrona = varLewaStrona, PrawaStrona = varPrawaStrona WHERE DrzewkoID = varRodzicID; END;
To jednak nie zmienia faktu, ze nie mozna zamknac kursora bo wszystkie wywolania rekurencyjne straca polaczenie z kursorem :|
----------------------------------------------------[ EDIT ]
Nie pytajcie sie jak to dziala, ale dziala

Oto kod, jezlei ktos by byl zainteresowany:
CREATE PROCEDURE `przebudujDrzewko`( IN varRodzicID INTEGER ( 11 ) , IN varLewaStrona INTEGER ( 11 ) , OUT varPrawaStrona INTEGER ( 11 )) NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE varDrzewkoID INT; DECLARE varKoniecWynikow BOOLEAN; DECLARE kursor CURSOR FOR SELECT DrzewkoID FROM Drzewko WHERE RodzicID = varRodzicID; DECLARE CONTINUE HANDLER FOR NOT FOUND SET varKoniecWynikow = TRUE; SET varPrawaStrona = varLewaStrona + 1; OPEN kursor; LOOP1: LOOP FETCH kursor INTO varDrzewkoID; IF varKoniecWynikow = TRUE THEN LEAVE LOOP1; END IF; CALL przebudujDrzewko(varDrzewkoID, varPrawaStrona, varPrawaStrona); END LOOP LOOP1; CLOSE kursor; UPDATE Drzewko SET LewaStrona = varLewaStrona, PrawaStrona = varPrawaStrona WHERE DrzewkoID = varRodzicID; SET varPrawaStrona = varPrawaStrona + 1; END;