8

特定のカテゴリのパスを再帰的に構築する関数を作成しようとしています

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の再帰的な保存関数とトリガーが許可されません。

これを回避するにはどうすればよいですか?このコードは、少なくともMySQLサーバーバージョン5.1が必要な通常のWebホスティングサービスでホストします。


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 ;

それから私はそれを呼び出すためにこのようなものを使用します

CALL getPath(72, @temp); SELECT @temp;
4

2 に答える 2

12

max_sp_recursion_depthを設定した場合でも、MySQLは再帰関数を許可しません。

max_sp_recursion_depthを設定すると、PROCEDUREで最大255回の再帰が可能になります。

したがって、return_pathにINOUT変数を使用して、関数をプロシージャに置き換えることをお勧めします。

于 2010-09-20T14:56:27.037 に答える
6

質問のストアドプロシージャから、* @ 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 ;

関数を作成します。

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 ;
于 2017-03-11T10:16:37.423 に答える