Firebird, хранимые процедуры и хлебные крошки

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Firebird, хранимые процедуры и хлебные крошки

Сообщение wofs » 09.12.2017 20:27:55

Доброго дня!
Имеем таблицу вида:
Код: Выделить всё
ID                IDPARENT                NAME

В ней хранится некое классическое дерево.
Стоит задача получить "Хлебные Крошки" (Навигационную цепочку) от указанного узла до корня.
Чтение документации привело меня к написанию такой хранимой процедуры:
Код: Выделить всё
create or alter procedure GETPARENTS_GROUP_CATALOG (
    ID integer)
returns (
    CID integer,
    PARENTID integer,
    NAME varchar(30))
as
declare variable VARBREADCRUMPS varchar(6000);
BEGIN
    varbreadcrumps = '';
  WHILE (:ID > 0) DO /* ищем до корня */
    BEGIN
      SELECT G.ID, G.IDPARENT, G.NAME
      FROM "GROUP-CATALOG" G
      WHERE G.ID = :ID
      INTO :CID, :PARENTID, :NAME;
      varbreadcrumps = NAME||'  '||varbreadcrumps;
      ID = :PARENTID; /* код родителя для следующей выборки */
      SUSPEND;
    END
END

Так как процедура селективная, то вызываю строкой:
Код: Выделить всё
select * from GETPARENTS_GROUP_CATALOG(10);

К моменту достижения корня дерева переменная varbreadcrumps содержит полный путь от указанного узла до корня.
Теперь стоит задача "свернуть" результат работы процедуры и вывести его(результат) одной строкой, содержащую только переменную varbreadcrumps.
Код: Выделить всё
select * from GETPARENTS_GROUP_CATALOG(IDNode3); =>> [Root  Node1  Node2  Node3]

В этом у меня проблема... Прошу помощи...

Добавлено спустя 8 минут 29 секунд:

Разобрался.
Надо перенести
Код: Выделить всё
SUSPEND;

И процедура примет вид:
Код: Выделить всё
create or alter procedure GETPARENTS_GROUP_CATALOG (
    ID integer)
returns (
    BREADCRUMPS varchar(6000),
    CID integer,
    PARENTID integer,
    NAME varchar(30))
as
declare variable VARBREADCRUMPS varchar(6000);
BEGIN
    varbreadcrumps = '';
  WHILE (:ID > 0) DO /* ищем до корня */
    BEGIN
      SELECT G.ID, G.IDPARENT, G.NAME
      FROM "GROUP-CATALOG" G
      WHERE G.ID = :ID
      INTO :CID, :PARENTID, :NAME;
      varbreadcrumps = NAME||' \ '||varbreadcrumps;
      breadcrumps = varbreadcrumps;
      ID = :PARENTID; /* код родителя для следующей выборки */
      --SUSPEND;
    END
    SUSPEND;
END
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird, хранимые процедуры и хлебные крошки

Сообщение alexs » 11.12.2017 10:41:07

Такие вещи можно делать рекурсивными запросами

Код: Выделить всё
CREATE TABLE TEST_1(
  TEST_1_ID INTEGER NOT NULL,
  TEST_1_OWN_ID INTEGER,
  TEST_1_NAME VARCHAR(150),
  PRIMARY KEY (TEST_1_ID)
);
   
with recursive aa (TEST_1_ID, TEST_1_OWN_ID, TEST_1_NAME)
as
  (
   select
     test_1.TEST_1_ID,
     test_1.TEST_1_OWN_ID,
     test_1.TEST_1_NAME
   from
     test_1
   where
     test_1.TEST_1_ID = 4

   union all

   select
     test_1.TEST_1_ID,
     test_1.TEST_1_OWN_ID,
     test_1.TEST_1_NAME || '\'|| aa. TEST_1_NAME
   from
     test_1
     inner join aa on test_1.TEST_1_ID = aa.TEST_1_OWN_ID
  )
select
  *
from
  aa
where
  aa.TEST_1_ID = 1


В запросе:
1 - это корневой узел
4 - это лист, от которого строим маршрут
Аватара пользователя
alexs
долгожитель
 
Сообщения: 3674
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Firebird, хранимые процедуры и хлебные крошки

Сообщение wofs » 11.12.2017 20:14:38

alexs писал(а):Такие вещи можно делать рекурсивными запросами

Хм... спасибо, не знал о такой возможности.
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru