2010-09-20 83 views
5

我試圖讓我嘗試運行使用沒有父母找到該函數遞歸構建的路徑特定類別的遞歸存儲函數

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 

功能(PARENT_ID = 0 )它工作正常,但是當我嘗試一個有parent_id> 0的類別時,我得到了1424遞歸存儲的函數和觸發器是不允許的。

我該如何解決這個問題?我將在一個普通的Web託管服務上託管這個代碼,該服務應該至少具有MySQL服務器版本5.1。


從艾克·沃克一些幫助後,我已經做出了precedure而不是正常工作

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 ; 

然後我用這樣的稱呼它

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

現在我正在開發與Ubuntu的MySQL服務器版本:5.1.41-3ubuntu12.6(Ubuntu) – Tirithen 2010-09-20 13:57:00

+0

我發現http://論壇.mysql.com/read.php?98,224107,224638#msg-224638談到SET max_sp_recursion_depth = N;其中N是允許的遞歸次數。但我仍然得到1424個遞歸存儲函數,並且不允許觸發器。 – Tirithen 2010-09-20 14:01:20

回答

7

MySQL不允許遞歸功能,即使你設置了max_sp_recursion_depth。

如果您設置了max_sp_recursion_depth,它允許在PROCEDURE中最多遞歸255次。

所以我建議你用一個過程替換你的函數,使用INOUT變量作爲return_path。

+0

感謝您對此進行整理,我現在已經制定了一個程序: – Tirithen 2010-09-21 01:34:43

+0

DROP PROCEDURE IF EXTREST 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 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 ACER 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 2010-09-21 01:35:08

1

從你提問中的存儲過程,*從@Ike沃克的幫助下,

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 ; 

創建一個函數:

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

接下來,你可以選擇:

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