Форум: "Базы";
Текущий архив: 2003.07.24;
Скачать: [xml.tar.bz2];
Вниз---|Ветка была без названия|--- Найти похожие ветки
← →
Cranium (2003-07-03 09:00) [0]Есть таблица 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?
← →
Zacho (2003-07-03 09:02) [1]C помощью рекурсивной ХП. Кстати, на www.ibase.ru есть статьи.
← →
Cranium (2003-07-03 09:10) [2]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:27) [3]Сейчас под рукой базы с подобным деревом нет, поэтому пишу по памяти, могу и ошибиться. Примерно так:
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:39) [4]Так мы всех конечные узлы получим, а не мне нужно конкретно заданного....
← →
Соловьев (2003-07-03 09:42) [5]
> Он ищет вверх по дереву, по аналогии можно и в низ построить,
> но
построй номер уровня и отсортируй в обратном порядке
← →
Johnmen (2003-07-03 09:44) [6]>Cranium ©
>а не мне нужно
А кому нужно ? Может все-таки тебе ?
Задавай вопрос нормально.
← →
Val (2003-07-03 11:48) [7]кто-то (кажется 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
← →
Cranium (2003-07-03 12:50) [8]
> Val © (03.07.03 11:48)
> кто-то (кажется GHOST)давным давно здесь мне помог этим
> скриптом:
Спасибо! Так или иначе пришлось менять структуру таблиц... С выше изложенным вариантом просто труба...
← →
kaif (2003-07-03 19:21) [9]Я делаю все проще.
У меня в бухгалтерской системе имеется дерево классов справочников.
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_ID FROM 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 я никогда не применяю.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.07.24;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c