Na bazie artykulu: http://www.sitepoint.com/article/hierarchi...data-database/3 o drzewkach SQLowych probuje stworzyc procedure skladowa do rpzebudowania drzewka.

Moja struktura tabeli Drzewko jest nastepujaca:
  1. CREATE TABLE `Drzewko` (
  2. `DrzewkoID` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `RodzicID` int(11) UNSIGNED DEFAULT NULL,
  4. `LewaStrona` int(11) UNSIGNED DEFAULT NULL,
  5. `PrawaStrona` int(11) UNSIGNED DEFAULT NULL,
  6. `Nazwa` varchar(200) collate utf8_polish_ci NOT NULL DEFAULT '',
  7. `PrzyjaznaNazwa` varchar(200) collate utf8_polish_ci NOT NULL DEFAULT '',
  8. `Sciezka` text collate utf8_polish_ci NOT NULL,
  9. PRIMARY KEY (`DrzewkoID`),
  10. UNIQUE KEY `DrzewkoID` (`DrzewkoID`)
  11. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;



Stworzylem soie taka procedure:
  1. CREATE PROCEDURE `przebudujDrzewko`( IN varRodzicID INTEGER ( 11 ) , IN varLewaStrona INTEGER ( 11 ))
  2. NOT DETERMINISTIC
  3. SQL SECURITY DEFINER
  4. COMMENT ''
  5. BEGIN DECLARE varDrzewkoID, varPrawaStrona INT;
  6. DECLARE varKoniecWynikow TINYINT;
  7.  
  8. DECLARE kursor CURSOR
  9. FOR SELECT DrzewkoID FROM Drzewko WHERE RodzicID = varRodzicID;
  10.  
  11. DECLARE CONTINUE HANDLER FOR NOT FOUND SET varKoniecWynikow = 1;
  12.  
  13. SET varPrawaStrona = varLewaStrona + 1;
  14. SET varKoniecWynikow = 0;
  15.  
  16.  
  17. OPEN kursor;
  18. WHILE varKoniecWynikow <> 1 DO
  19. FETCH kursor INTO varDrzewkoID; CALL przebudujDrzewko(varDrzewkoID, varPrawaStrona);
  20. END WHILE;
  21.  
  22. CLOSE kursor;
  23.  
  24. UPDATE Drzewko
  25. SET LewaStrona = varLewaStrona,
  26. PrawaStrona = varPrawaStrona
  27. WHERE DrzewkoID = varRodzicID;
  28. 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 winksmiley.jpg)

Tak wyglada poprawiona procedura:
  1. CREATE PROCEDURE `przebudujDrzewko`( IN varRodzicID INTEGER ( 11 ) , IN varLewaStrona INTEGER ( 11 ))
  2. NOT DETERMINISTIC
  3. SQL SECURITY DEFINER
  4. COMMENT ''
  5. BEGIN DECLARE varDrzewkoID, varPrawaStrona INT;
  6. DECLARE varKoniecWynikow BOOLEAN;
  7.  
  8. DECLARE kursor CURSOR
  9. FOR SELECT DrzewkoID FROM Drzewko WHERE RodzicID = varRodzicID;
  10.  
  11. DECLARE CONTINUE HANDLER FOR NOT FOUND SET varKoniecWynikow = TRUE;
  12. SET varPrawaStrona = varLewaStrona + 1;
  13.  
  14.  
  15. OPEN kursor;
  16. LOOP1: LOOP
  17. FETCH kursor INTO varDrzewkoID; IF varKoniecWynikow = TRUE THEN
  18. /*CLOSE kursor;*/
  19. LEAVE LOOP1;
  20. END IF;
  21.  
  22.  
  23. CALL przebudujDrzewko(varDrzewkoID, varPrawaStrona);
  24. END LOOP LOOP1;
  25. CLOSE kursor;
  26.  
  27.  
  28. UPDATE Drzewko
  29. SET LewaStrona = varLewaStrona,
  30. PrawaStrona = varPrawaStrona
  31. WHERE DrzewkoID = varRodzicID;
  32. 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 biggrin.gif

Oto kod, jezlei ktos by byl zainteresowany:
  1. CREATE PROCEDURE `przebudujDrzewko`( IN varRodzicID INTEGER ( 11 ) , IN varLewaStrona INTEGER ( 11 ) , OUT varPrawaStrona INTEGER ( 11 ))
  2. NOT DETERMINISTIC
  3. SQL SECURITY DEFINER
  4. COMMENT ''
  5. BEGIN DECLARE varDrzewkoID INT;
  6. DECLARE varKoniecWynikow BOOLEAN;
  7.  
  8. DECLARE kursor CURSOR
  9. FOR SELECT DrzewkoID FROM Drzewko WHERE RodzicID = varRodzicID;
  10.  
  11. DECLARE CONTINUE HANDLER FOR NOT FOUND SET varKoniecWynikow = TRUE;
  12. SET varPrawaStrona = varLewaStrona + 1;
  13.  
  14.  
  15. OPEN kursor;
  16. LOOP1: LOOP
  17. FETCH kursor INTO varDrzewkoID; IF varKoniecWynikow = TRUE THEN
  18. LEAVE LOOP1;
  19. END IF;
  20.  
  21.  
  22. CALL przebudujDrzewko(varDrzewkoID, varPrawaStrona, varPrawaStrona);
  23. END LOOP LOOP1;
  24. CLOSE kursor;
  25.  
  26.  
  27. UPDATE Drzewko
  28. SET LewaStrona = varLewaStrona,
  29. PrawaStrona = varPrawaStrona
  30. WHERE DrzewkoID = varRodzicID;
  31.  
  32. SET varPrawaStrona = varPrawaStrona + 1;
  33. END;