2010-09-20 10 views
5

Sto cercando di fare una funzione che costruisce in modo ricorsivo un percorso per una specifica categoriafunzioni ricorsive memorizzati 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 

Quando si tenta di eseguire questa funzione con una categoria che non ha genitori (parent_id = 0) funziona bene ma quando provo una categoria che ha un parent_id> 0 ottengo 1424 Le funzioni memorizzate ricorsive e i trigger non sono consentiti.

Come posso aggirare questo? Ho intenzione di ospitare questo codice su un normale servizio di web hosting che dovrebbe avere almeno il server MySQL versione 5.1.


Dopo qualche aiuto da Ike Walker ho fatto un precedure, invece, che funziona bene

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 ; 

allora io uso qualcosa di simile a chiamarlo

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

In questo momento sto sviluppando su Ubuntu con la versione MySQL-Server: 5.1.41-3ubuntu12.6 (Ubuntu) – Tirithen

+0

Ho trovato http: // forums .mysql.com/read.php? 98,224107,224638 # msg-224638 che parla di SET max_sp_recursion_depth = N; dove N è il numero di ricorsi da consentire. Ma ho ancora 1424 funzioni memorizzate ricorsive e trigger non sono consentiti. – Tirithen

risposta

7

MySQL non consente ricorsiva FUNZIONI, anche se si imposta max_sp_recursion_depth.

Consente fino a 255 ricorsione in una PROCEDURA se si imposta max_sp_recursion_depth.

Quindi si consiglia di sostituire la funzione con una procedura, utilizzando una variabile INOUT per il percorso di ritorno.

+0

Grazie per aver risolto questo problema, ora ho fatto una procedura: – Tirithen

+0

PROCEDURA DROP SE ESISTE getPath; DELIMITER // CREATE PROCEDURE getPath (IN ID_catego INTSIGNATO, OUT ritorno_path TEXT) INIZIO \t DECLARE parent_id INT NON SEGNALATO; \t DECLARE path_result TEXT; \t SET max_sp_recursion_depth = 50; \t SELECT CONCAT ('/', ac.name) IN return_path FROM article_categories AS ac WHERE ac.id = category_id; \t SELECT ac.parent_id INTO parent_id FROM article_categories AS ac WHERE ac.id = category_id; \t IF parent_id> 0 THEN \t \t CALL getPath (parent_id, path_result); \t \t SELECT CONCAT (path_result, return_path) INTO return_path; \t END IF; END // DELIMITER; – Tirithen

1

dalla stored procedure nella sua interrogazione, * con l'aiuto di @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 ; 

Creare una funzione:

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

Avanti, è possibile selezionare:

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