Рекурсивный запрос в MySQL с использованием хранимой процедуры и CURSOR

Я расширяю нашу систему пользователей / групп, чтобы включить динамические группы, которые состоят из других членов групп. У меня три стола users, groups, а также relationships,

Для простоты предположим, что пользователи содержат только одно поле user_id и группы содержат только group_id, relationships использует три поля: user_id, group_id, related_group_id представлять как пользователя в группу, так и отношения между группами.

Динамически заполненная групповая иерархия будет выглядеть примерно так:

пользователей A, B, C принадлежат группе 1 и пользователи D, E, F принадлежат к группе 2. Все они представлены в таблице отношений как (user_id, group_id):

A,1
B,1
C,1
D,2
E,2
F,2

Динамическая группа 3 будет иметь две группы, чтобы сгруппировать записи отношений (group_id, related_group_id):

3,1
3,2

Чтобы лучше проиллюстрировать мою проблему, давайте добавим динамическую группу 4 и включить его в группу 3:

4,3

Собираем воедино то, что я узнал о MySQL CURSOR я создал следующую хранимую процедуру fetch_inheritance_groups:

DROP PROCEDURE IF EXISTS `fetch_inheritance_groups`;

CREATE PROCEDURE `fetch_inheritance_groups`(IN parent_id INT)
    READS SQL DATA
    BEGIN

    DECLARE inherit_id char(32);
    DECLARE eol BOOLEAN;
    DECLARE inherit_cur CURSOR FOR SELECT r.Related_Group_ID FROM usr_relationships r WHERE r.Group_ID = parent_id AND r.Related_Group_ID IS NOT NULL;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET eol = TRUE;

    OPEN inherit_cur;
    inherited: LOOP
        FETCH inherit_cur INTO inherit_id;

        IF eol 
            THEN
            CLOSE inherit_cur;
            LEAVE inherited;
        ELSE
            CALL fetch_inheritance_groups(inherit_id);
        END IF;

        SELECT inherit_id;

    END LOOP inherited;

END;

... который называется с...

CALL fetch_inheritance_groups(4);

... и возвращает ожидаемые результаты

3
2
1

Здесь начинается моя проблема, они возвращаются как три отдельных набора результатов, а не как три строки в одном наборе результатов, и, во-вторых, результаты предназначены для использования в запросе, например:

SELECT r.uer_id FROM relationships r WHERE r.group_id = 4 OR r.group_id IN (CALL fetch_inheritance_groups(4));

Итак, я надеюсь, что кто-то может ответить на три вопроса:

1. Должен ли я использовать CURSOR здесь или есть альтернатива, которая получит такой же рекурсивный результат?

2. Как я могу получить результаты обратно в одном наборе результатов, чтобы его можно было использовать таким же образом, как и для подвыбора?

3. Как правильно использовать результаты CALL потому что я не могу, по крайней мере, постараться заставить приведенный выше пример оператора SELECT работать? Я считаю, что это потому, что я не могу использовать CALL встроенный, но я не уверен.

0 ответов

Другие вопросы по тегам