2010-09-20 18 views
5

Ich versuche, eine Funktion zu machen, die rekursiv einen Pfad für eine bestimmte Kategorierekursive gespeicherte Funktionen in 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 

Wenn ich mit einer Kategorie versuchen zu laufen diese Funktion erstellt, die keine Eltern mehr hat (parent_id = 0) Es funktioniert gut, aber wenn ich eine Kategorie versuche, die eine Parent_id> 0 hat, bekomme ich 1424 Recursive gespeicherte Funktionen und Trigger sind nicht erlaubt.

Wie kann ich das umgehen? Ich werde diesen Code auf einem regulären Webhosting-Dienst hosten, der mindestens MySQL Server Version 5.1 haben sollte.


Nach etwas Hilfe von Ike Walker Ich habe eine precedure stattdessen gemacht, die

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 ; 

funktioniert gut ich dann so etwas wie diese verwenden es zu nennen

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

Momentan entwickle ich auf Ubuntu mit MySQL-Server Version: 5.1.41-3ubuntu12.6 (Ubuntu) – Tirithen

+0

Ich habe http: // Foren gefunden .mysql.com/read.php? 98,224107,224638 # msg-224638 das über SET spricht max_sp_recursion_depth = N; Wobei N die Anzahl der zu erlaubenden Rekursionen ist. Aber ich bekomme immer noch 1424 Recursive gespeicherte Funktionen und Trigger sind nicht erlaubt. – Tirithen

Antwort

7

MySQL nicht rekursive erlauben FUNKTIONEN, auch wenn Sie max_sp_recursion_depth festlegen.

Es erlaubt bis zu 255 Rekursion in einem PROCEDURE, wenn Sie max_sp_recursion_depth festlegen.

Daher empfehle ich, dass Sie Ihre Funktion durch eine Prozedur ersetzen, die eine INOUT-Variable für den Rückgabepfad verwendet.

+0

Vielen Dank für das Aussortieren, ich habe jetzt stattdessen eine Prozedur gemacht: – Tirithen

+0

DROP PROCEDURE IF EXISTS getPath; DELIMITER // CREATE PROCEDURE getPath (IN category_id INT UNSIGNED, OUT return_path TEXT) BEGIN \t DECLARE- parent_id INT UNSIGNED; \t DECLARE path_result TEXT; \t SET max_sp_recursion_depth = 50; \t SELECT CONCAT ('/', ac.name) INTO Rückkehrpfad FROM article_categories AS ac WHERE ac.id = Kategorie_ID; \t SELECT ac.parent_id INTO parent_id FROM Artikelkategorien AS ac WHERE ac.id = category_id; \t IF parent_id> 0 DANN \t \t CALL getPath (parent_id, path_result); \t \t SELECT CONCAT (path_result, return_path) INTO return_path; \t ENDE IF; ENDE // DELIMITER; – Tirithen

1

aus der gespeicherten Prozedur in Ihrer Frage, * mit Hilfe von @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 ; 

Erstellen Sie eine Funktion:

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$$ 

Als Nächstes können Sie wählen:

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