2010-09-20 12 views
5

Próbuję utworzyć funkcję, która rekurencyjnie buduje ścieżkę do określonej kategoriirekurencyjne funkcje przechowywanych w MySQL

CREATE FUNCTION getPath(inId INT) 
RETURNS TEXT 
DETERMINISTIC 
BEGIN 
    DECLARE return_path TEXT; 
    DECLARE return_parent_id INT; 
    SELECT CONCAT('/', name) INTO return_path FROM article_categories WHERE id = inId; 
    SELECT parent_id INTO return_parent_id FROM article_categories WHERE id = inId; 

    IF return_parent_id > 0 THEN 
     SELECT CONCAT(getPath(return_parent_id), return_path) INTO return_path; 
    END IF; 

    RETURN return_path; 
END 

Kiedy próbuję uruchomić tę funkcję, z kategorii, która nie ma rodziców (parent_id = 0) działa dobrze, ale gdy próbuję kategorii, która ma parent_id> 0 otrzymuję 1424 Rekursywnie przechowywane funkcje i wyzwalacze są niedozwolone.

Jak to obejść? Zamierzam hostować ten kod na zwykłej internetowej usłudze hostingowej, która powinna mieć przynajmniej serwer MySQL w wersji 5.1.


Po jakiejś pomocy od Ike Walker Zrobiłem precedure zamiast tego, że działa dobrze

DROP PROCEDURE IF EXISTS getPath; 
DELIMITER // 
CREATE PROCEDURE getPath(IN category_id INT UNSIGNED, OUT return_path TEXT) 
BEGIN 
    DECLARE parent_id INT UNSIGNED; 
    DECLARE path_result TEXT; 

    SET max_sp_recursion_depth=50; 

    SELECT CONCAT('/', ac.name), ac.parent_id INTO return_path, parent_id FROM article_categories AS ac WHERE ac.id = category_id; 

    IF parent_id > 0 THEN 
     CALL getPath(parent_id, path_result); 
     SELECT CONCAT(path_result, return_path) INTO return_path; 
    END IF; 
END // 
DELIMITER ; 

Następnie używać coś takiego nazwać

CALL getPath(72, @temp); SELECT @temp; 
+0

W tej chwili pracuję nad Ubuntu z wersją MySQL-Server: 5.1.41-3ubuntu12.6 (Ubuntu) – Tirithen

+0

Znalazłem http: // fora .mysql.com/read.php? 98224107,224638 # msg-224638, który mówi o SET max_sp_recursion_depth = N; gdzie N to liczba rekursji do zaakceptowania. Ale nadal otrzymuję 1424 Rekursywnie przechowywane funkcje i wyzwalacze są niedozwolone. – Tirithen

Odpowiedz

7

MySQL nie zezwala rekurencyjne FUNKCJE, nawet jeśli ustawisz max_sp_recursion_depth.

Umożliwia maksymalnie 255 rekursji w PROCEDURZE, jeśli ustawisz max_sp_recursion_depth.

Polecam, aby zastąpić funkcję procedurą, używając zmiennej INOUT dla funkcji return_path.

+0

Dziękuję za uporządkowanie tego, teraz zrobiłem procedurę: – Tirithen

+0

PROCEDURA DROP JEŚLI ZNAJDUJE getPath; DELIMITER // CREATE PROCEDURE getPath (IN ID_ID INT UNSIGNED, OUT return_path TEXT) BEGIN \t DECLARE parent_id INT UNSIGNED; \t DECLARE ścieżka_reklamowa TEKST; \t SET max_sp_recursion_depth = 50; \t WYBIERZ KONCAT ("/", ac.name) DO ścieżki powrotnej FROM article_categories JAK ac GDZIE ac.id = category_id; \t SELECT ac.parent_id INTO parent_id Z article_categories JAK AK GDZIE ac.id = category_id; JEŻELI strona_gospodarzowa> 0 NASTĘPNIE \t \t CALL getPath (id_odbiorczy, id_sesji); \t \t SELECT CONCAT (ścieżka_opcji, ścieżka_do_instrukcji) INTO ścieżka_instrukcji; \t END IF; END // DELIMITER; – Tirithen

1

z procedury przechowywane w pytaniu * Z pomocą @Ike Walker,

DROP PROCEDURE IF EXISTS getPath; 
DELIMITER $$ 
CREATE PROCEDURE getPath(IN category_id INT UNSIGNED, OUT return_path TEXT) 
BEGIN 
    DECLARE parent_id INT UNSIGNED; 
    DECLARE path_result TEXT; 
    SET max_sp_recursion_depth=50; 

    SELECT CONCAT('/', ac.name), ac.parent_id INTO return_path, parent_id FROM article_categories AS ac WHERE ac.id = category_id; 
    IF parent_id > 0 THEN 
     CALL getPath(parent_id, path_result); 
     SELECT CONCAT(path_result, return_path) INTO return_path; 
    END IF; 
END $$ 
DELIMITER ; 

Utwórz funkcję:

DROP FUNCTION IF EXISTS getPath; 
CREATE FUNCTION getPath(category_id INT) RETURNS TEXT DETERMINISTIC 
BEGIN 
    DECLARE res TEXT; 
    CALL getPath(category_id, res); 
    RETURN res; 
END$$ 

Następnie można wybrać:

SELECT category_id, name, getPath(category_id) AS path FROM article_categories ;