Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

рекурсивная процедура в Firebird [Firebird 1.5]


_Sheriff ©   (2004-11-30 09:48:00) 

Добрый день.
Имеется таблица, реализующая древовидную структуру.
подскажите как правильно организовать рекурсивную процедуру для обхода дерева с произвольного места с получением индексов элементов дерева.
Пытаюсь организовать процедуру следующим образом:

CREATE PROCEDURE UPDATETREELIST (PARENTID INTEGER)
RETURNS (FLEX INTEGER)
AS
DECLARE VARIABLE IDX INTEGER;
DECLARE VARIABLE TEMP INTEGER;
BEGIN
for
  select D.ID
  from tbl_data D
  where D.parentdeviceid = :ParentID
  into :Idx
do begin
  for
    select Flex
    from UPDATETREELIST(:Idx)
    into :Temp
  do begin
    Flex = :Idx;
    suspend;
  end
 end
 Flex = :Idx;
 suspend;
END

этот код выводит только первую группу индексов несколько раз.
(для разработки использую IBExpert)


Deniz   (2004-12-02 08:13:00) [1]

> Sergey_Masloff   (02.12.04 07:56) [11]
Все нормально ;-)
А просто хотел узнать у автора, для чего все это надо, а то может какой другой вариант подойдет лучше.


Sergey_Masloff   (2004-12-02 07:56:00) [2]

Deniz ©   (02.12.04 06:49) [10]
Если ваш ответ относился конкретно к этой процедуре то признаю справедливость Вашего высказывания.
 Я, конечно, имел в виду общий случай применения "деревянных" структур. С их использованием проблем не возникает.
 Вобщем, рубанул вас шашкой сгоряча.


Deniz   (2004-12-02 06:49:00) [3]

> Sergey_Masloff   (01.12.04 11:10) [9]
>То же самое.

Что эначит тоже самое? Не вот это ли "Не надо говорить чего не знаете."? Если да, то Вам надо пересмотреть текст процедуры, и повнимательнее.
Если в процедуру передать в качестве параметра ID самой верхней ветки и в таблице, как Вы говорите несколько миллионов, то проблема сразу ясно и нарисуется. Если просто обход дерева, то проблем почти нет, но возврат на клиента всех дочерних веток вызывает двоякие чувства.


Sergey_Masloff   (2004-12-01 11:10:00) [4]

DSKalugin ©   (30.11.04 19:23) [5]
>а не проще ли на программном/клиентском уровне это делать?
>такими процедурами можно повесить SQLсервер
 Не надо говорить чего не знаете. Нормально написаными процедурами подобного рода сервер не повесишь а удобство они приносят огромное. Хотя бы тем что вся логика в ОДНОМ месте а не в трех десятках клиентов неизвестно каких версий.

Deniz ©   (01.12.04 06:57) [7]
>При большой вложенности и большом кол-ве записей в этой таблице >могут быть всякие неприятности.
То же самое. При вложенности до 700 с чем-то (это зашитая константа для Windows для NIX вроде 1000) и числом записей несколько миллионов - проблем нет абсолютно никаких (если процедуры написаны прямыми руками)


YurikGL   (2004-12-01 07:25:00) [5]

Если есть таблицы
1)Sborki
 IdSborka
 ...
2)IerhLink
 IdIerhLink
 IdSborkaParent
 IdSborkaChild
 CountS (количество)

то можно так

CREATE PROCEDURE RECURALLNODES(
   IDSBORKAIN INTEGER,
   COUNTSIN INTEGER)
RETURNS (
   IDSBORKAOUT INTEGER,
   COUNTSOUT INTEGER)
AS
begin
 IdSborkaOut=IdSborkaIn;
 CountSOut=CountSIn;
 Suspend;
 for Select IdSborkaChild, sum(CountS*:CountSIn)
     From IerhLink
     where IdSborkaParent=:IdSborkaIn
     group by IdSborkaChild
     into :IdSborkaOut, :CountSOut
     do begin

        For Select IdSborkaOut, CountSOut
            From RecurAllNodes(:IdSborkaOut,:CountSOut)
            InTo :IdSborkaOut,:CountSOut
            do suspend;

        End

end


Deniz   (2004-12-01 06:57:00) [6]

> _Sheriff   (30.11.04 14:52) [4]
Расскажи про задачу поконкретнее. При большой вложенности и большом кол-ве записей в этой таблице могут быть всякие неприятности.


Val (from Donetsk)   (2004-11-30 22:27:00) [7]

DSKalugin ©   (30.11.04 19:23) [5]
Аргументы?
Повесить можно чем и что угодно, как вы понимаете.


DSKalugin   (2004-11-30 19:23:00) [8]

а не проще ли на программном/клиентском уровне это делать?
такими процедурами можно повесить SQLсервер


_Sheriff   (2004-11-30 14:52:00) [9]

сейчас так:

for
  select Flex
  from UPDATETREELIST(:Idx)
  into :Flex
do begin
  suspend;
end


Deniz   (2004-11-30 13:56:00) [10]

...
 for
   select Flex
   from UPDATETREELIST(:Idx)
    into :Temp
 do begin
    Flex = :Idx;
   suspend;
 end
 ...
Так и должно быть? Или все же Flex = :Temp;?


_Sheriff   (2004-11-30 10:31:00) [11]

благодарю. буду разбираться.


Johnmen   (2004-11-30 09:49:00) [12]

Ищи на ibase.ru. Там был пример с комментариями...


Наверх

Титульная страница Поиск, карта сайта Написать письмо