ďťż
Podstrony
|
telcocafeid | parent 1 | 0 2 | 1 3 | 1 4 | 2 5 | 2 6 | 0 7 | 6Tak się głowię i nie mogę niczego wymyślić. Chcę zrobić tak, by podczas usuwania wpisu z id=1 zostało usunięte całe drzewo, czyli wpisy od 1. do 5. Czy da się to zrobić poza rekurencją z poziomu PHP?Przepraszam bardzo, ale gdzie tu zasada co do owego "drzewa" ? Bo nie rozumiem, dlaczego dla ID=1 usuwane są niby wartości 0..2 ? Weź no wytłumacz po polsku! id to identyfikator elementu, a parent to identyfikator rodzica. Przykładowe drzewo (przedstawione przeze mnie):-1 |-2 | |-4 | |-5 |-3 -6 |-7I teraz jak najprościej usunąć całą gałąź z id=1? Użytkownik andrzej_aa edytował ten post 16 marzec 2008, 22:24 musisz miec jakis kontener (chocby tablice) przechodujaca idy. 1 wpisujesz do niej id do usuniecia, i usuwasz ten element. 2. szukasz wszystkich elementow ktore jako parent maja id dowolnego element z tablicy, i usuwasz ten id ktorego szukasz z tej tablicy. dopisujesz idy wyszukanych elementow do tablicy, i usuwasz te elementy. 3. powtarzasz krok 2gi az tablica nie bedzie pusta. Użytkownik Deadeye edytował ten post 23 marzec 2008, 02:00 Tak, tylko to jest rekurencja w PHP (o ile się nie mylę :-P), a mi chodzi o coś "taniego" w MySQL. W MySQL też możesz stosować rekurencję :) - Tworzysz funkcję MySQL - Zapytaniem ją wywołujesz - Ona wywołuje samą siebie dla wszystkich podrzędnych wpisów - Usuwa aktualny wpis No no, funkcje są fajne (dzięki! dotychczas myślałem, że są tylko w MsSQL :-P). Jednak jak na początki potrzebuję pomocy :-) Próbowałem na różne sposoby i nie wychodzi mi. To mój ostatni kod:CREATE FUNCTION PROPPARENTIDS (`_id` int) RETURNS int UNSIGNED BEGIN DELETE FROM `menu` WHERE `parent` IN (SELECT DROPPARENTIDS(`_id`)); RETURN (SELECT `id` FROM `menu` WHERE `parent`=`_id`); END;Funkcja powinna jednak zwracać tablicę (ale nie wiem jak to zrobić). Mimo tego przy wywołaniu SELECT DROPPARENTIDS(1) zwraca Recursive stored functions and triggers are not allowed Co jest sprzeczne z założeniem. Mam wszystkie uprawnienia w bazie. Szczerze mówiąc nie tego się spodziewałem, nie wiedziałem że funkcje nie mogą być rekursywne. Ale z tego co widzę procedury już mogą być. Taki szybki test :) CREATE PROCEDURE ext (id INT) BEGIN CALL ext(id+1); SELECT id; END; ... Query OK, 0 rows affected (0.02 sec) CALL ext(4); ERROR 1456 (HY000): Recursive LIMIT 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine ext Co oznacza dwie rzeczy: procedury mogą być rekursywne; należy ustawić odpowiednią zmienną by na to pozwolić. A to że procedura nic bezpośrednio nie zwróci nie powinno być zbyt wielkim problemem.. można użyć TEMPORARY TABLE jeśli już koniecznie potrzebny nam wynik. Można też w ogóle się nie przejmować zwracaniem wyników i wewnątrz funkcji robić SELECT... i na wynikach tego zapytania uruchamiać samego siebie (by to powtórzyć + usunąć wpisy) ^^^^ kolorowanie składni - genialne ^^^^ Użytkownik Einzeinbleth edytował ten post 23 marzec 2008, 21:49 Tak, tylko to jest rekurencja w PHP (o ile się nie mylę :-P), a mi chodzi o coś "taniego" w MySQL. jaka rekurencja o_O zwykla petla while( tablica niepusta), i bezproblemowo ja mozna napisac jako procedure skladowana w sql ;] No i mam takie zapytania:delimiter // CREATE PROCEDURE DROPPARENTIDS (IN `_id` int) BEGIN DECLARE `_tid` int; DECLARE `_ok` int DEFAULT 0; DECLARE `_cur` CURSOR FOR SELECT `id` FROM `menu` WHERE `parent`=`_id`; DECLARE CONTINUE HANDLER FOR NOT FOUND SET `_ok`=1; OPEN `_cur`; REPEAT FETCH `_cur` INTO `_tid`; CALL DROPPARENTIDS(`_tid`); UNTIL `_ok` END REPEAT; CLOSE `_cur`; DELETE FROM `menu` WHERE `parent`=`_id`; END; // delimiter ; SET GLOBAL max_sp_recursion_depth=1024; CALL DROPPARENTIDS(1);I występuje kolejny błąd, tym razem braku pamięci. #1436 - Thread stack overrun: 103228 bytes used of a 196608 byte stack, and 96000 bytes needed. Use 'mysqle -O thread_stack=#' to specify a bigger stack. Poddaję się. Zrobię to w PHP - przynajmniej nie będę się tyle męczył. |
|||
Sitedesign by AltusUmbrae. |