Форум: "Базы";
Текущий архив: 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