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

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

Дерево в БД [D7, IB6.x]


Страницы:   1 2 3 4

goozman ©   (2004-05-06 10:12:00) 

Помогите пожалуйста, есть таблица, главные поля (ID, PARENT_ID) по ним строится дерево- по полю ID я могу добратся к самому верхнему родителю, а теперь вопрос помогите создать запрос по которому можно по родителю (самому верхнему) узнать все дочерние его ветки! Очень надеюсь на Вашу помощь!


Johnmen   (2004-05-06 12:37:00) [21]

>Мунька
>Всего-навсего ответила на вопрос, где при построении дерева не использовалась НИКАКАЯ специфика СУБД,

Неужели ? А что по поводу временной таблицы ? Откуда она ? И что с ней ?
И насколько это эффективно ?

>все в рамках Ansi - стандарта.

В смысле ?

>И еще не штурмовал, а штурмовалА

Виноват. Сразу не сообразил...:)


Курдль   (2004-05-06 12:29:00) [22]


> Мунька   (06.05.04 12:18) [39]
> Всего-навсего ответила на вопрос, где при построении дерева
> не использовалась НИКАКАЯ специфика СУБД, все в рамках Ansi
> - стандарта. Если за вас УЖЕ извлечены все потомки - это
> хорошо, здесь показано все с 0 (почти, как format c:).

Про "никакую специфику". А если Ваш юзер не имеет привелегий на создание временных таблиц?
И как Вы сами-то оцениваете "select в цикле" с клиента? Это нормально?


Курдль   (2004-05-06 12:18:00) [23]


> aList.Sort(@SortCompareIndex);

Не обязательно - можно и без @.


> и вообще не понятно к чему твой код :)

Да "не вынесла душа поэта" :))) Привел код, который выстраивает данные в древовидную структуру и еще суммирует остатки по счетам "вверх по иерархии". Это не 10 строк, а аж 30...


Мунька   (2004-05-06 12:18:00) [24]

>Неужели чтобы "передать опыт"? То, что Вы понаписали внутри ХП -> чудовищно! Какие-то временные таблицы, бесчисленные селекты...
>Что Вы хотели показать?
Всего-навсего ответила на вопрос, где при построении дерева не использовалась НИКАКАЯ специфика СУБД, все в рамках Ansi - стандарта. Если за вас УЖЕ извлечены все потомки - это хорошо, здесь показано все с 0 (почти, как format c:).

Не считаю CB круче Делфи, просто пишу на нем, мне удобнее.
И еще не штурмовал, а штурмовалА


}|{yk   (2004-05-06 12:14:00) [25]

http://delphimaster.ru/cgi-bin/forum.pl?id=1083829796&n=1


Соловьев   (2004-05-06 12:11:00) [26]


> aList.Sort(SortCompareIndex);

странно...
aList.Sort(@SortCompareIndex);?
и вообще не понятно к чему твой код :)


Johnmen   (2004-05-06 12:09:00) [27]

>Курдль ©   (06.05.04 12:03) [32]
>Что Вы хотели показать?

А то ты не понял ? :)
Показать, что CB круче D, и эту крутизну успешно штурмовал тов. Мунька
Кстати, что-то текста маловато он привел... Требую продолжения банкета !


Соловьев   (2004-05-06 12:08:00) [28]


> Можно, но в данной программе хрен редьки не слаще

ну-ну... советую взглянуть на исходники готовых DBTreeView


Курдль   (2004-05-06 12:08:00) [29]

Вот клиент:

//------------------------------------------------------------------------------
procedure TfrmAccounts.SortAccList(aList: TList);
var y, iy: Integer; py: ptrAcc;
 procedure BuildLink(var ptr: ptrAcc; var Index: Integer);
 var x: Integer; px: ptrAcc;
 begin
  inc(Index);
  for x:=0 to aList.Count-1 do
   begin
    px:=aList.Items[x];
    if (px.pr = ptr.id) and (px.index = 0) then
     begin
      px.index:=Index;
      px.level:=ptr.level+1;
      BuildLink(px, Index);
      ptr.dt0:=ptr.dt0+px.dt0;
      ptr.kt0:=ptr.kt0+px.kt0;
     end;
   end;
 end;
begin
 if aList = nil then Exit;
 iy:=1;
 for y:=0 to aList.Count-1 do
  begin
   py:=aList.Items[y];
   if py.pr = 0 then
    begin
     py.index:=iy;
     BuildLink(py,iy);
    end;
  end;
 aList.Sort(SortCompareIndex);
end;
//------------------------------------------------------------------------------


Соловьев   (2004-05-06 12:06:00) [30]


>  То, что Вы понаписали внутри ХП - чудовищно!

это как раз клиент :)


Курдль   (2004-05-06 12:03:00) [31]


> Мунька   (06.05.04 11:48) [24]

ЗАЧЕМ ВЫ ЭТО ВЫЛОЖИЛИ???
Неужели чтобы "передать опыт"? То, что Вы понаписали внутри ХП - чудовищно! Какие-то временные таблицы, бесчисленные селекты...
Что Вы хотели показать?


Мунька   (2004-05-06 12:01:00) [32]

>При использовании AddObject можно в узле хранить ссылку на >структуру где хранить об узле кучи инфы, котора облегчает >построение.
Можно, но в данной программе хрен редьки не слаще


Мунька   (2004-05-06 11:59:00) [33]

>Это все об одном дереве????????!!!!!!!   8-()
>Я же сказал 10 строк, а не 510!
Там разные варианты - вывод в грид, в дерево, поиск потомков.. то есть это еще и визуальная обработка


Соловьев   (2004-05-06 11:59:00) [34]


> Это все об одном дереве????????!!!!!!!   8-()
> Я же сказал 10 строк, а не 510!

конечно когда за тебя все сделали

> Но я, чаще всего, беру TdxDBTreeList, подставляю ему набор
> данных и не парюсь :)



> Мунька   (06.05.04 11:55) [27]
> >>слабенько :) А как насчет AddObject?
> Никак. Не помню из каких соображений, но вариант с добавлением
> объекта был отброшен. Наверное, из-за того, что объект должен
> быть наследником TObject, все-таки, а не просто целым числом.

При использовании AddObject можно в узле хранить ссылку на структуру где хранить об узле кучи инфы, котора облегчает построение.


Курдль   (2004-05-06 11:55:00) [35]


> Мунька

Это все об одном дереве????????!!!!!!!   8-()
Я же сказал 10 строк, а не 510!


Мунька   (2004-05-06 11:55:00) [36]

>>слабенько :) А как насчет AddObject?
Никак. Не помню из каких соображений, но вариант с добавлением объекта был отброшен. Наверное, из-за того, что объект должен быть наследником TObject, все-таки, а не просто целым числом.


Соловьев   (2004-05-06 11:49:00) [37]


> DepListId->Add(IntToStr(ADOQDepart->FieldByName("id_division")->AsInteger));

слабенько :) А как насчет AddObject? ИМХО возможностей больше. И для ИБ есть уже готовые с исходниками. Брать на www.fibplus.com.ua в старье


Мунька   (2004-05-06 11:48:00) [38]

//И напоследок, есть предок, извлечь всех его потомков
bool TDM::SelectLastLevel(WideString ConnectionADO, int id_parent)
{
TStringList *Id= new TStringList(), *list_parent = new TStringList()  ;
int  i;    // * list_id = new [1], size_list_id = 1,
AnsiString InString;
 if(ADOQLastLevel->Active)
 ADOQLastLevel->Close();

 ADOQLastLevel->ConnectionString = ConnectionADO;
 list_parent->Add(IntToStr(id_parent));
 do{
     ADOQLastLevel->SQL->Clear();
    ADOQLastLevel->SQL->Add("SELECT id_division, id_parent FROM  tdivision WHERE id_parent IN(");
          InString = "";
    for(i=0; i<list_parent->Count; i++)
    {
     if ( ((i+1)%100)==0)
     {
       ADOQLastLevel->SQL->Add(InString);
       InString = "";
     }
     InString += list_parent->Strings[i];
     if(i<(list_parent->Count-1) )
      InString +=", ";
     else InString +=")";
    }
     ADOQLastLevel->SQL->Add(InString);
    ADOQLastLevel->SQL->Add("ORDER BY id_parent, id_division");
     try{
        if(!ADOQLastLevel->Prepared)
         ADOQLastLevel->Prepared = true;

        ADOQLastLevel->Open();
        }
     catch(...)
    {
        delete Id;
        delete list_parent;
       return false;
    }

      for(i=0; i<list_parent->Count; i++)
      {
        ADOQLastLevel->Filtered = false;
        ADOQLastLevel->Filter = "id_parent = "+ list_parent->Strings[i];
        try{
        ADOQLastLevel->Filtered = true;
        }
        catch(...)
        {
         continue;
        }
           if(ADOQLastLevel->RecordCount==0)
         Id->Add(list_parent->Strings[i]);

      }//end for

          list_parent->Clear();
      ADOQLastLevel->Filtered = false;
      ADOQLastLevel->First();
      while(!ADOQLastLevel->Eof)
      {
       list_parent->Add(ADOQLastLevel->FieldByName("id_division")->AsString);
       ADOQLastLevel->Next();
      }

    }
 while(ADOQLastLevel->RecordCount>0);
   
   ADOQLastLevel->SQL->Clear();
   ADOQLastLevel->SQL->Add("delete from tdivision_tmp");
    try{
         if(!ADOQLastLevel->Prepared)
         ADOQLastLevel->Prepared = true;

        ADOQLastLevel->ExecSQL();

      }
  catch(...)
  {
    delete Id;
   delete list_parent;
   return false;
  }

        ADOQLastLevel->SQL->Clear();
    ADOQLastLevel->SQL->Add("INSERT INTO tdivision_tmp ");
    ADOQLastLevel->SQL->Add("SELECT * FROM  tdivision WHERE id_division IN(");
   
        InString = "";
    for(i=0; i<Id->Count; i++)
    {
     if ( ((i+1)%100)==0)
     {
       ADOQLastLevel->SQL->Add(InString);
       InString = "";
     }
     InString += Id->Strings[i];
     if(i<(Id->Count-1) )
      InString +=", ";
     else InString +=")";
    }
       ADOQLastLevel->SQL->Add(InString);

     try{
         if(!ADOQLastLevel->Prepared)
         ADOQLastLevel->Prepared = true;

        ADOQLastLevel->ExecSQL();

      }
  catch(...)
  {
   delete Id;
   delete list_parent;
   return false;
  }

   delete Id;
   delete list_parent;
   return true;
}


Мунька   (2004-05-06 11:48:00) [39]

//Вывод в дерево
bool TDM::SelectAllDepartmentToTree(WideString ConnectionADO, TTreeView *TreeViewDep)
{
int RecNo;

if(ADOQDepart->Active)
 ADOQDepart->Close();

 ADOQDepart->ConnectionString = ConnectionADO;
ADOQDepart->SQL->Clear();
ADOQDepart->SQL->Add("SELECT * FROM  tdivision ORDER BY id_parent, id_division");
try{
  ADOQDepart->Open();
}
catch(...)
{
 return false;
}
ADOQDepart->First();
TreeViewDep->Items->Clear();
while(!ADOQDepart->Eof&&(ADOQDepart->FieldByName("id_parent")->AsInteger==-1 ) )
{
 // DepList->Add(ADOQDepart->FieldByName("name_division")->AsString);
  TreeViewDep->Items->Add(NULL, ADOQDepart->FieldByName("name_division")->AsString);

  RecNo =ADOQDepart->RecNo;
 // RecursDepartmentList(DepList, ADOQDepart->FieldByName("id_division")->AsInteger, DepListId);
  RecursDepartmentList(TreeViewDep, ADOQDepart->FieldByName("id_division")->AsInteger, TreeViewDep->Items->Item[TreeViewDep->Items->Count-1]);
  ADOQDepart->RecNo=RecNo;
  ADOQDepart->Next();
}
// ADOQDepart->

return true;
}
//рекурсия построения дерева
void TDM::RecursDepartmentList(TTreeView *TreeViewDep, int id_parent, TTreeNode *NodeParent)
{
int RecNo;

 while(!ADOQDepart->Eof)
 {
  if(ADOQDepart->FieldByName("id_parent")->AsInteger==id_parent)
   {
    TreeViewDep->Items->AddChild(NodeParent, ADOQDepart->FieldByName("name_division")->AsString);
    RecNo = ADOQDepart->RecNo;
    RecursDepartmentList(TreeViewDep, ADOQDepart->FieldByName("id_division")->AsInteger, TreeViewDep->Items->Item[TreeViewDep->Items->Count-1]);
    ADOQDepart->RecNo=RecNo;

   }
   ADOQDepart->Next();
 }

}


Мунька   (2004-05-06 11:47:00) [40]

// и кусок кода, для вызова всего этого хозяйства, одна функция выводит в грид SetStringListToGrig, вторая - в дерево
DM->SelectAllDepartmentToTree
...........................................
DeparmentList = new TStringList();
DeparmentListId = new TStringList();
DM->SelectAllDepartment(ConnectionADO, DeparmentList, DeparmentListId);
  ClearGrid(SGDivision, MIN_ROWCOUNT_DEPARTMENT);
 SetStringListToGrig(SGDivision, DeparmentList, MIN_ROWCOUNT_DEPARTMENT, 0);
 SGDivisionSelectCell(Sender,  0, 1,CanSelect);
 DM->SelectAllDepartmentToTree(ConnectionADO, TreeViewDep);
.......... дальше по коду...........................
//----------------------SetStringListToGrig вывод извлеченного дерева в грид------
void SetStringListToGrig(TStringGrid *sg, TStringList *sl, int min_rowcount, int col_num)
{
int i;
for(i=0; i< sl->Count; i++)
{
  if(i==(sg->RowCount-sg->FixedRows ))
      sg->RowCount +=min_rowcount;
  sg->Cells[col_num][i+sg->FixedRows] = sl->Strings[i];

}

}


Страницы:   1 2 3 4

Наверх

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