SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 18.12.2012 10:09:48

Greenlancer
Участник
Зарегистрирован: 18.12.2012
Сообщений: 5

Хранимка на удаление древовидной структуры.

Есть таблица описывающая все каталоги, в ней есть столбцы ID_Cat-идентификатор каталога, и ID_Parent-идентификатор родителя этого каталога. Необходимо написать хранимку которая будет удалять каталог по заданному ID_Cat со всеми подкаталогами.
Пытался реализовать через еще одну таблицу в которую заносятся id каталога который необходимо удалить и его lvlC вложенности, при этом ID_Cat поданный на вход процедуре lvlC=0, каждый следующий уровень вложенности lvlC+1.

[syntax=mysql]
CREATE DEFINER = 'root'@'localhost'
PROCEDURE filesystem.TR11(IN id_c VARCHAR(255))
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE lvl  INT;
  DECLARE a    INT;
  DECLARE cur1 CURSOR FOR SELECT id
                          FROM
                            TT
                          WHERE
                            lvlC = lvl-1;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  CREATE TABLE TT
  (
    id INT PRIMARY KEY,
    lvlC INT
  );
  SET lvl = 0;
  INSERT INTO TT (id, lvlC) VALUES (id_c, lvl);
  SET lvl = lvl + 1;
SET a = id_c;

  WHILE EXISTS (SELECT ID_Cat
              FROM
                catalog, TT
              WHERE
                catalog.ID_Parent = a
                AND TT.lvlC = lvl-1)
DO
               
  OPEN cur1;
  REPEAT
    FETCH cur1 INTO a;
    IF NOT done THEN

      INSERT INTO TT (id, lvlC) VALUES (
        (SELECT ID_Cat
         FROM
           catalog
         WHERE
           catalog.ID_Parent = a), lvl);

    END IF;

  UNTIL done
  END REPEAT;
  SET lvl = lvl + 1;
  CLOSE cur1;

END WHILE;

  DELETE
  FROM
    filesystem.catalog
  WHERE
    ID_Cat = (SELECT id
              FROM
                TT);

  DROP TABLE TT;
END
 


Она работает но удаляет только каталог поданный на вход Процедуре.
Как это еще можно реализовать??

Неактивен

 

#2 18.12.2012 10:37:57

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Хранимка на удаление древовидной структуры.

Посмотрите здесь.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#3 18.12.2012 12:06:15

Greenlancer
Участник
Зарегистрирован: 18.12.2012
Сообщений: 5

Re: Хранимка на удаление древовидной структуры.

Спасибо за полезную ссылку, но меня интересует построение иерархии вниз от каталога, а в примере представлено нахождение полного пути к каталогу.
Некоторая сложность заключается в том что родительский каталог всегда один, а вот подкаталогов может быть огромное множество, у каждого из которых еще свое множество подкаталогов, а это всё множество необходимо удалить.

Неактивен

 

#4 25.12.2012 07:26:37

ita
Участник
Зарегистрирован: 24.09.2008
Сообщений: 19

Re: Хранимка на удаление древовидной структуры.

Нужно делать через рекурсию. Посмотрите  книгу М. Кузнецов, И. Симдянов, "MySql на примерах", 2007 г. Там на стр. 414 рассмотрено решение аналогичной задачи с использованием рекурсии.
А вообще задача очень интересная.

Неактивен

 

#5 25.12.2012 09:26:49

ita
Участник
Зарегистрирован: 24.09.2008
Сообщений: 19

Re: Хранимка на удаление древовидной структуры.

структура таблицы catalogs:
(*id_catalog, name, id_parent)

delimiter //
create procedure delcat (IN id INT)
begin
declare is_end int default 0;
declare id_cat int default 0;
  declare cat cursor for
    select id_catalog from catalogs where id_parent = id;
declare continue handler for not found set is_end=1;

open cat;
wet: LOOP
    FETCH cat INTO id_cat;
    IF id_cat >0 THEN CALL delcat(id_cat);
    END IF;
     DELETE FROM catalogs WHERE id_catalog =id_cat;
   IF is_end THEN  LEAVE wet;
   END IF;
  END LOOP wet;
CLOSE cat;
  DELETE FROM catalog WHERE id_catalog=id;
END
//
delimiter ;

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson