2010-09-20 40 views
5

Tôi đang cố gắng để thực hiện một chức năng mà đệ quy xây dựng một con đường cho một loại cụ thểchức năng lưu trữ đệ quy trong 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 

Khi tôi cố gắng chạy chức năng này với một thể loại mà không có cha mẹ (PARENT_ID = 0) nó hoạt động tốt nhưng khi tôi thử một loại có parent_id> 0 tôi nhận được 1424 Các hàm và trình kích hoạt được lưu trữ đệ quy không được phép.

Làm cách nào để giải quyết vấn đề này? Tôi sẽ lưu trữ mã này trên một dịch vụ lưu trữ web thông thường cần có ít nhất là phiên bản máy chủ MySQL 5.1.


Sau một số sự giúp đỡ từ Ike Walker Tôi đã thực hiện một precedure thay vào đó hoạt động tốt

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 ; 

sau đó tôi sử dụng một cái gì đó như thế này để gọi nó là

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

Hiện tại tôi đang phát triển trên Ubuntu với phiên bản MySQL-Server: 5.1.41-3ubuntu12.6 (Ubuntu) – Tirithen

+0

Tôi đã tìm thấy http: // diễn đàn .mysql.com/read.php? 98,224107,224638 # msg-224638 nói về SET max_sp_recursion_depth = N; trong đó N là số lần thu thập để cho phép. Nhưng tôi vẫn nhận được 1424 Chức năng và trình kích hoạt được lưu trữ đệ quy không được phép. – Tirithen

Trả lời

7

MySQL không cho phép đệ quy FUNCTION, ngay cả khi bạn đặt max_sp_recursion_depth.

Nó cho phép lên tới 255 đệ quy trong một THỦ TỤC nếu bạn đặt max_sp_recursion_depth.

Vì vậy, tôi khuyên bạn nên thay thế hàm của mình bằng một quy trình, sử dụng biến INOUT cho return_path.

+0

Cảm ơn bạn đã sắp xếp xong việc này, tôi đã thực hiện một quy trình thay thế: – Tirithen

+0

THỦ TỤC DROP NẾU THỜI TIẾT getPath; DELIMITER // TẠO THỦ TỤC XỬ LÝ TRƯỚC (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 WHERE ac.id = category_id; \t NẾU parent_id> 0 THEN \t \t GỌI getPath (parent_id, path_result); \t \t CHỌN CONCAT (path_result, return_path) INTO return_path; \t END IF; END // DELIMITER; – Tirithen

1

Từ các thủ tục lưu trữ trong câu hỏi của bạn, * với sự giúp đỡ từ @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 ; 

Tạo một hàm:

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

Tiếp theo, bạn có thể chọn:

SELECT category_id, name, getPath(category_id) AS path FROM article_categories ; 
Các vấn đề liên quan