Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.08.13;
Скачать: [xml.tar.bz2];

Вниз

Подскажите как сделать вывод базы данных в виде дерева   Найти похожие ветки 

 
ceval ©   (2006-06-06 15:07) [0]

Здравствуйте
Подскажите как сделать вывод базы данных в виде дерева
например есть файл mdb и из него будут браться данныя
что то вроде этого (Главная - Отдел- Подразделения)
[]
|
[]___
|  |  |
[] [][]


 
Сергей М. ©   (2006-06-06 15:12) [1]


> как сделать вывод базы данных в виде дерева


Никак.


 
Sergey13 ©   (2006-06-06 15:15) [2]

DBTreeView - можно искать готовые, можно самому делать.


 
ANB ©   (2006-06-06 15:16) [3]

Это смотря чем и кто БД создавал. Используй оракл, он, правда не увидит твою mdb, зато в нем connect by есть.


 
Ega23 ©   (2006-06-06 15:21) [4]


> Никак.


Не ври. Хочешь выведу?


 
Ega23 ©   (2006-06-06 15:22) [5]

Есть компонент, писал сам, но функциональность специфичная, под общие нужды не заточена.


 
ANB ©   (2006-06-06 15:24) [6]


> Ega23 ©   (06.06.06 15:22) [5]

Ну ты крут. Просто взять и вывести mdb файл в виде дерева.
Кстати, судя по всему у автора обычная связка мастер-детал, только БД он скорее всего рисовать еще не начинал, иначе догадался бы запостить структуру таблиц.


 
Ega23 ©   (2006-06-06 15:26) [7]


> Ну ты крут. Просто взять и вывести mdb файл в виде дерева.


Согласись, что запрос, возвращающий вообще всю базу, написать можно. Сложно, геморно и главное - никому не нужно. Но можно.


 
Сергей М. ©   (2006-06-06 15:43) [8]


> Ega23 ©   (06.06.06 15:21) [4]


Валяй..


 
Курдль ©   (2006-06-06 15:45) [9]

1. Упорядочить (рекурсия)
2. Выявить уровни (там же)
3. Отобразить (tree list)


 
Ega23 ©   (2006-06-06 15:53) [10]


> Валяй..


Давай запрос. KeyField, ParentKeyField, DisplayField, ImageField.
Можно и другие, но этого достаточно.


 
Курдль ©   (2006-06-06 16:00) [11]


> DisplayField, ImageField

И шо оно туда выдаст? Таки настоящие деревья? 8-()


 
Ega23 ©   (2006-06-06 16:02) [12]


> И шо оно туда выдаст? Таки настоящие деревья? 8-()

DisplayField - это то, что в TTreeNode.Text будет
ImageField - поле с BLOB, пока bmp 16х16. Будет "присовокуплена к узлу" дерева.


 
Курдль ©   (2006-06-06 16:06) [13]

Думаю, что Сергей М. ©   (06.06.06 15:43) [8] имел в виду то, что результат запроса будет линейный, как ни старайся. Т.е. просто набор записей :(
Если ты имеешь в виду, что нарисуешь деревянно-упорядоченный запрос (не функцию и не на оракле), то мне тоже интересно. Можно без картинок :)


 
Сергей М. ©   (2006-06-06 16:12) [14]


> Ega23 ©   (06.06.06 15:53) [10]


Запросы эти сам строй) .. Оно мне надо ?

До кучи сразу объясняй автору, чем отличается база данных от табличных (и иных) объектов в ее составе.


 
Ega23 ©   (2006-06-06 16:12) [15]


> Если ты имеешь в виду, что нарисуешь деревянно-упорядоченный
> запрос (не функцию и не на оракле), то мне тоже интересно.
>


Я с MSSQL работаю. А имел ввиду, что написал компонент TDBTreeView. Для работы ему надо задать все эти поля [10] + TDataSource.


 
Курдль ©   (2006-06-06 16:16) [16]


> А имел ввиду, что написал компонент TDBTreeView.


А знаменитую функцию IncDay() тоже ты написал? :)
Этой заразы полно: dxDBTreeList, cxDBTreeView, ehDBTree (типа того).


 
Ega23 ©   (2006-06-06 16:32) [17]


> А знаменитую функцию IncDay() тоже ты написал


Нет. Но она у меня есть.


> Этой заразы полно: dxDBTreeList, cxDBTreeView, ehDBTree
> (типа того).


Первое денег стоит. Немалых. Про вторые - ничего не знаю. А технологию создания ДБ-компонентов всё равно надо было поднимать: уж больно специфичные компоненты получались. Вот на дереве и тренировался...


 
Курдль ©   (2006-06-06 16:50) [18]


> Вот на дереве и тренировался...


Да уж... Я как-то тоже тренировался. Осваивал двойную буферизацию, drag-n-drop скроллирование и прочую хрень. Ничего так контрол получился - без тормозов и глюков. Но он принес больше пользы в плане ООП. Столько типов и коллекций в одном компоненте мне раньше не приходилось делать...


 
Ega23 ©   (2006-06-06 17:01) [19]


> Но он принес больше пользы в плане ООП.


Ну, скажем, мне он помог понять тонкости работы DB-Aware компонентов в Delphi.


 
Amoeba ©   (2006-06-06 17:16) [20]


> Этой заразы полно: dxDBTreeList, cxDBTreeView, ehDBTree
> (типа того).

Даже в JVCL есть (взят из RALib). Очень приличный компонент, позволяет все редактирование непосредственно в дереве, включая перемещение ветвей. С моей подачи в 3-й версии библиотеки то пофиксили один нехороший баг.


 
ANB ©   (2006-06-06 17:50) [21]


> Ega23 ©   (06.06.06 15:26) [7]

Это ежели в mdb гарантировано база mssql и не кривая. :)


 
ceval ©   (2006-06-07 20:22) [22]

спасиба буду разбираться
может стоит попробывать тогда использываться какой нибудь DBTreeView и db


 
kaif ©   (2006-06-07 21:50) [23]

Я обычно делаю дерево так:
Беру обычный TTreeView.
На событие OnCollapse удаляю все дочерние Nodes текущего Node.
На событие OnExpand создаю дочерние Nodes одним уровнем ниже для распахиваемого пункта, обращаясь всякий раз SQL-запросом к базе данных. При создании дочернего Node, если пункт имеет в базе дочерние (HAS_CHILDREN = 1), то устанавливаю для таких принудительно свойство Node.HasChildren := True.
При запуске программы создаю корневой Node, запросив одну строку из базы данных.
ID храню в свойстве Node.Data, явно приведя к Pointer.

Структуру таблицы делаю примерно такую:
ID INTEGER,
PARENT_ID INTEGER,
NAME VARCHAR(50),
HAS_CHILDREN INTEGER

В триггере AFTER DELETE делаю:
IF (NOT EXISTS(SELECT ID FROM MyTable WHERE ID = OLD.PARENT_ID) THEN
UPDATE MyTable SET HAS_CHILDREN = 0;

В триггере AFTER INSERT делаю:
UPDATE MyTable SET HAS_CHILDREN = 1;

В триггере AFTER UPDATE делаю и то и другое вместе:
IF (OLD.PARENT_ID <> NEW.PARENT_ID) THEN
BEGIN
 IF (NOT EXISTS(SELECT ID FROM MyTable WHERE ID = OLD.PARENT_ID) THEN
 UPDATE MyTable SET HAS_CHILDREN = 0;
 UPDATE MyTable SET HAS_CHILDREN = 1;
END

Можно, конечно, обойтись и без триггеров и без поля HAS_CHILDREN, сделав такой запрос к базе, который вернет признак наличия потомков у объектов данного уровня. Но моя практика показывает, что удобнее все же иметь такое поле. Это упрощает жизнь и в других ситуациях.

Кайф этого подхода (каждый раз перезапрашивать ветвь) в том, что дерево легко пересвечивать после вставки в него нового пункта. Достаточно вызвать Collapse и Expand родительской ветви.

А вообще я сохраняю в базе данных (для каждого юзера) степень раскрытости его папок просто в виде строки ID, разделенных запятой. При отображении дерева в первый раз я считываю эту строку из базы и просто отыскиваю последовательно Node-ы, у которых в Data лежит следующий ID - затем вызываю Expand для этого Node-а. А при закрытии формы сканирую дерево и формирую строку из ID для тех Nodes[i], которые сейчас распахнуты (HasChildren = True). И сохраняю эту строку в базе данных.

Этот подход мне представляется наилучшим.
Код настолько прост, что мне даже не требовалось его оформлять в компонент. Всего два обработчика событий. И парочка функций.


 
kaif ©   (2006-06-07 21:53) [24]

Извиняюсь, все напутал в текстах триггеров:

В триггере AFTER DELETE делаю:
IF (NOT EXISTS(SELECT ID FROM MyTable WHERE PARENT_ID = OLD.PARENT_ID) THEN
UPDATE MyTable SET HAS_CHILDREN = 0 WHERE ID = OLD.PARENT_ID;

В триггере AFTER INSERT делаю:
UPDATE MyTable SET HAS_CHILDREN = 1  WHERE ID = NEW.PARENT_ID;

В триггере AFTER UPDATE делаю и то и другое вместе:
IF (OLD.PARENT_ID <> NEW.PARENT_ID) THEN
BEGIN
IF (NOT EXISTS(SELECT ID FROM MyTable WHERE ID = OLD.PARENT_ID) THEN
UPDATE MyTable SET HAS_CHILDREN = 0 WHERE ID = OLD.PARENT_ID;
UPDATE MyTable SET HAS_CHILDREN = 1 WHERE ID = NEW.PARENT_ID;
END


 
Сергей М. ©   (2006-06-08 16:05) [25]


> kaif ©   (07.06.06 21:53) [24]


При всем к тебе, Ашот, уважении не кажется ли тебе, что ты (с твоим-то опытом !) мог бы объяснить Авторпу, что "вывод базы данных в виде дерева" - это нонсенс ?


 
Ega23 ©   (2006-06-08 16:24) [26]


> Я обычно делаю дерево так:
> Беру обычный TTreeView.
> На событие OnCollapse удаляю все дочерние Nodes текущего
> Node.
> На событие OnExpand создаю дочерние Nodes одним уровнем
> ниже для распахиваемого пункта, обращаясь всякий раз SQL-
> запросом к базе данных.


Это всё, конечно, замечательно. Но только в том случае, когда не нужно дерево с другими DB-контролами синхронизировать.
А у меня задача - есть один набор данных. Есть DBGrid, в котором отражены некоторые поля этого НД. Есть дерево, где все записи этого НД выведены в виде иерархической структуры. И есть картинка, на которой эти объекты изображены.
Ткнулся на запись в гриде - выбрался соответствующий узел в дереве - подсветилась соответствующая картинка на графике.
Сделал принудительный Locate НД "извне" - во всех трёх контролах установились правлиьные текущие объекты.
Выбрал картинку на графике - всё то же самое.
Самое "западло" в этой ситуации - что компановка программы может быть разная. Может быть только дерево. Или только графика. Или только грид. Или и графика и дерево. И т.д.


 
Сергей М. ©   (2006-06-08 16:58) [27]


> Ega23 ©   (08.06.06 16:24) [26]


При всем при том ты так и не сподобился объяснить, как ты умудряешься вывести "в виде дерева" именно базу данных, а не некий НД)

Про "Не ври" может возьмешь слова обратно ?


 
Ega23 ©   (2006-06-08 17:35) [28]


> При всем при том ты так и не сподобился объяснить, как ты
> умудряешься вывести "в виде дерева" именно базу данных,
> а не некий НД)
>


Ну конечно НД, а не "базу данных". Хотя если сильно постараться, то можно написать запрос, который выведет ПОЛНОЕ содержимое БД в один НД.


> Про "Не ври" может возьмешь слова обратно ?


Если тебя это успокоит, то пожалуйста - беру свои слова обратно.


 
rar ©   (2006-06-08 21:14) [29]

Что то я не совсем понял триггеры.
Поле HAS_CHILDREN что имеет только значения 0 и 1 что ли

Я делаю по другому, прибавляю или удаляю единицу и в этом поле храниться количество дочерних элементов

Правда пришлось это делать без триггеров.

С ними ругается что таблица находиться в изменении у меня СУБД ORACLE


 
atruhin ©   (2006-06-08 21:23) [30]


> Правда пришлось это делать без триггеров.

Вот это плохо. Раньше или позже грабли будут точно. Если в таблицах не более нескольких тысяч записей можно не хранить кол-во, а просто динамически запрашивать.


 
rar ©   (2006-06-09 18:51) [31]


> Вот это плохо. Раньше или позже грабли будут точно. Если
> в таблицах не более нескольких тысяч записей можно не хранить
> кол-во, а просто динамически запрашивать.
> <Цитата>

Если динамически делать запрос, тогда вообще зачем это поле :-))

Оно и предназначено для рисования "плюсика" в TreeView



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2006.08.13;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.041 c
3-1149834666
Snik
2006-06-09 10:31
2006.08.13
Как правильно организовать запрос?


2-1153736129
Delphi basic
2006-07-24 14:15
2006.08.13
Выбор значения поля в DBGrid из списка и сопоставление


2-1153578887
Belorus
2006-07-22 18:34
2006.08.13
Два вопроса. Классы и Изображения


2-1153713090
Vovan33
2006-07-24 07:51
2006.08.13
Internet Explorer


2-1153818848
linsa
2006-07-25 13:14
2006.08.13
Картинка из Access в Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский