2016-06-02 5 views
2

Пытается собрать некоторые данные по иерархии для отправки третьим лицам и направлено в this post.Сохраняемая процедура тайм-аута

После попытки настроить его на мой прецедент на SQL Fiddle, хранимая процедура сохраняет тайм-аут.
Итак, я попробовал его локально дважды (через PhpMyAdmin).
Когда я пытаюсь перезагрузить PMA в браузере после вызова хранимой процедуры, я просто получаю вечный счетчик «ожидания ответа» (более 10 или 20 минут).

Я предполагаю, что с моим кодом SP что-то не так ???

CREATE TABLE foo 
    (`id` int, `name` varchar(100), `parentId` int, `path` varchar(100)) 
// 

INSERT INTO foo (`id`, `name`, `parentId`, `path`) 
VALUES (1, 'discrete', 0, NULL), 
     (2, 'res', 1, NULL), 
     (3, 'smt', 2, NULL), 
     (4, 'cap', 1, NULL), 
     (5, 'ind', 1, NULL), 
     (6, 'smt', 4, NULL), 
     (7, 'tant', 6, NULL), 
     (8, 'cer', 6, NULL) 
// 

CREATE PROCEDURE updatePath() 
BEGIN 
DECLARE cnt, n int; 
    SELECT COUNT(*) INTO n FROM foo WHERE parentId = 0; 
    UPDATE foo a, foo b SET a.path = b.name WHERE b.parentId IS NULL AND a.parentId = b.id; 
    SELECT count(*) INTO cnt FROM foo WHERE path IS NULL; 
    while cnt > n do 
     UPDATE foo a, foo b SET a.path = concat(b.path, '|', b.id) WHERE b.path IS NOT NULL AND a.parentId = b.id; 
     SELECT count(*) INTO cnt FROM foo WHERE path IS NULL; 
    end while; 
END// 

EDIT
Ожидаемые результаты:

VALUES (1, 'discrete', 0, '1'), 
     (2, 'res', 1, '1|2'), 
     (3, 'smt', 2, '1|2|3'), 
     (4, 'cap', 1, '1|4'), 
     (5, 'ind', 1, '1|5'), 
     (6, 'smt', 4, '1|4|6'), 
     (7, 'tant', 6, '1|4|6|7'), 
     (8, 'cer', 6, '1|4|6|8'); 
+0

Что касается вызова SP в SqlFiddle, я понимаю, что они должны быть вызваны из панели схемы. Если я ошибаюсь, сообщите нам. – mOrloff

+0

И BTW, я открыт для совершенно разных подходов (например, временных таблиц или ???), если есть преимущества для этого. – mOrloff

ответ

1

После хорошей ночи спать, Я взял @ Дрю, и я прошел через него по одному компьютеру за раз.
Получил работу. Вот где я оставляю это:

CREATE TABLE foo 
    (`id` int, `name` varchar(100), `parentId` int, `path` varchar(100)) 
// 

INSERT INTO foo 
    (`id`, `name`, `parentId`, `path`) 
VALUES 
    (1, 'dscr', 0, NULL), 
    (2, 'res', 1, NULL), 
    (3, 'smt', 2, NULL), 
    (4, 'cap', 1, NULL), 
    (5, 'ind', 1, NULL), 
    (6, 'chp', 4, NULL), 
    (7, 'tant', 6, NULL), 
    (8, 'cer', 6, NULL) 
// 

CREATE PROCEDURE updatePath() 
BEGIN 
DECLARE cnt, n int; 

    SELECT COUNT(*) INTO n FROM foo WHERE parentId = 0; -- n is now 1 
    SELECT COUNT(*) INTO cnt FROM foo WHERE path IS NULL; -- cnt is now 8 

    UPDATE foo child, foo parent  -- each child now has its parent and own ID's in the path 
     SET child.path = CONCAT(parent.id, '|', child.id) 
     WHERE parent.parentId = 0 
     AND child.parentId = parent.id; 

    WHILE cnt > n DO 
     UPDATE foo child, foo parent -- concat parent's path and own ID into each empty child's path 
      SET child.path = concat(parent.path,'|',child.id) 
      WHERE parent.path IS NOT NULL 
      AND child.parentId = parent.id; 

     SELECT COUNT(*) INTO cnt -- decrement cnt 
      FROM foo 
      WHERE path IS NULL; 

    END WHILE; 

    UPDATE foo -- set path for any top-level categories 
     SET path = id 
     WHERE path IS NULL; 

END// 

call updatePath()// 

Не стесняйтесь критиковать.
Надеюсь, это поможет кому-то еще некоторое время.

0

Вы пытаетесь сделать автореферентное присоединиться, чтобы создать иерархию?

выберите a.name, parentName = b.name из обув а, внешнего соединения Foo б на ( a.id = b.parentId )

+0

Да, но больше, чем ваше предложение. Мы пытаемся создать и сохранить строку пути через самореференционное соединение. Кроме того, мне интересно, подходит ли ваше предложение для другого аромата SQL, потому что некоторые из них выглядят не совсем правильно (через мои ограниченные объективы MySQL) – mOrloff

+0

Да, извините, что это было для SQL Server, но главный должен иметь значение true , – hivie7510

+0

Да, правильный принцип. Потребность в этом ** рекурсивно ** заключается в том, что он немного перегружает мою глубину XP – mOrloff