![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
---|Ветка была без названия|---
Cranium © (2003-07-03 09:00:00)Есть таблица GROUP_USERдля хранения дерева вида
ID_USER Integer
ID_PARENT Integer
NIC_USER Varchar(25)
Корень
/ \
Узел1 Узел2
/ \ \
Узел3 Узел4 Узел5
/ \ \
Узел6 Узел7 Узел8
Задача Нужно получить "листья" Узала1....
Получить все "листья" получается с помощью ХП
............
FOR SELECT E1.ID_GROUP
FROM GROUP_USER E1
WHERE (NOT EXISTS (SELECT * FROM GROUP_USER E2 WHERE E2.ID_GROUP = E2.ID_PARENT ))
INTO :CURENT_ID_GROUP
DO
...........
А как быть с потомками Узла1?
kaif (2003-07-03 19:21:00) [1]Я делаю все проще.
У меня в бухгалтерской системе имеется дерево классов справочников.
CREATE TABLE CLASS (
CLASS_ID TIDENTITY,
PARENT_ID TIDENTITY,HAS_CHILDREN TBOOLEAN DEFAULT 0,
NAME TCLASS_NAME,
TABLE_NAME TTABLE_NAME,
IS_ABSTRACT TBOOLEAN,
CONSTRAINT PK_CLASS PRIMARY KEY (CLASS_ID),
CONSTRAINT AK_CLASS_NAME UNIQUE (NAME),
CONSTRAINT AK_CLASS_TABLE_NAME UNIQUE (TABLE_NAME)
);
Хранимая процедура CLASS_TREE возвращает все сочетания старший- младший, вот текст:
/*Процедура возвращает сочетания всех старших справочников ко всем младшим и к себе*/
CREATE PROCEDURE CLASS_TREE
RETURNS (PARENT_ID INTEGER, CHILD_ID INTEGER)
AS
BEGIN
PARENT_ID = 0;
CHILD_ID = 0;
SUSPEND;
FOR SELECT CLASS_IDFROM CLASS
INTO :CHILD_ID
DO BEGIN
PARENT_ID = CHILD_ID;
WHILE (PARENT_ID <> 0) DO
BEGIN
SUSPEND;
SELECT PARENT_ID FROM CLASS WHERE CLASS_ID = :PARENT_ID
INTO :PARENT_ID;
END
END
END
Далее, если мне нужны все потомки узла PARENT_ID = 113,
я просто делаю запрос:
SELECT * FROM CLASS_TREE WHERE PARENT_ID= 113;
Никаких LEVEL я никогда не применяю.
Cranium (2003-07-03 12:50:00) [2]
> Val © (03.07.03 11:48)
> кто-то (кажется GHOST)давным давно здесь мне помог этим
> скриптом:
Спасибо! Так или иначе пришлось менять структуру таблиц... С выше изложенным вариантом просто труба...
Val (2003-07-03 11:48:00) [3]кто-то (кажется GHOST)давным давно здесь мне помог этим скриптом:
create procedure sp_getchildren(selfid/*, selflevel*/)
returns(id, parentid, name/*, lev*/)
as
begin
for
select id, parentid, name
from items
where parentid = :selfid
order by name
into :id, :parentid, :name
do
begin
/* level = selflevel + 1;*/
suspend;
for
select id, parentid, name/*, lev*/
from sp_getchildren(:id/*, :lev/*)
order by name
into :id, :parentid, :name/*, :lev*/
do
suspend;
end
end
Johnmen (2003-07-03 09:44:00) [4]>Cranium ©
>а не мне нужно
А кому нужно ? Может все-таки тебе ?
Задавай вопрос нормально.
Соловьев (2003-07-03 09:42:00) [5]
> Он ищет вверх по дереву, по аналогии можно и в низ построить,
> но
построй номер уровня и отсортируй в обратном порядке
Cranium (2003-07-03 09:39:00) [6]Так мы всех конечные узлы получим, а не мне нужно конкретно заданного....
Zacho (2003-07-03 09:27:00) [7]Сейчас под рукой базы с подобным деревом нет, поэтому пишу по памяти, могу и ошибиться. Примерно так:
CREATE PROCEDURE GET_CHILD(PARENT_ID INTEGER)
RETURNS (CHILD_ID INTEGER)
AS
DECLARE VARIABLE ID INTEGER;
BEGIN
FOR SELECT ID FROM TREE WHERE PARENT_ID=:PARENT_ID INTO :ID DO
BEGIN
SUSPEND;
GET_CHILD(:ID);
END
END
Cranium (2003-07-03 09:10:00) [8]Zacho © (03.07.03 09:02)
Да сотрел я их дело в том что там вариант:
CREATE PROCEDURE GETPARENTS (ID INTEGER)
RETURNS (DID INTEGER, OID INTEGER, NAME VARCHAR(30))
AS
BEGIN
WHILE (:ID > 0) DO /* ищем до корня */
BEGIN
SELECT O.ID, O.PARENT, O.NAME
FROM OBJECTS O
WHERE O.ID = :ID
INTO :DID, :OID, :NAME;
ID = :OID; /* код родителя для следующей выборки */
SUSPEND;
END
END
Он ищет вверх по дереву, по аналогии можно и в низ построить, но не получается в цикле использовать FOR SELRCT, а без него только одна ветвь строится, как не изголялся конструкция вида
WHILE [условие] DO
begin
for select *
..........
не получается:((( Надеюсь ты меня понял
Zacho (2003-07-03 09:02:00) [9]C помощью рекурсивной ХП. Кстати, на www.ibase.ru есть статьи.