powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Аналог симлинков в дереве
6 сообщений из 6, страница 1 из 1
Аналог симлинков в дереве
    #32127950
mitrich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

У меня имеется таблица с древовидной структурой обьектов:

SQL> desc PARTS_TYPES

Name Null? Type
----------------------------------------- -------- -------------
ID NOT NULL NUMBER
ID_PARENT NUMBER
NAME VARCHAR2(200)
...
REFERENCE NUMBER

В ней древовидную структуру определяют поля ID и ID_PARENT. В то же время есть поле REFERENCE для организации своего рода ссылок на уже существующие ветви дерева. На мой взгляд, тут уместно вспомнить аналогию с symbolic links в Unix-системах. Таким образом, если в REFERENCE (по умолчанию там при вставке NULL) указать ID существующего элемента дерева, то это и будет ссылка. Мне необходимо составить такой запрос, который бы создавал иллюзию работы этих ссылок, т.е. прикреплял бы к записи-ссылке фиктивные дочерние элементы-строки, являющиеся дубликатами дочерних элементов той строки, на которую смотрит ccылка.

Я не могу составить запрос, который бы корректно реализовывал эту схему. Я пробовал три пути реализации:

1) вариант с организацией дерева по фиктивному полю REF_ID и дублированием дочерних элементов

select
a.*,
(case when a.REFERENCE is NULL
then a.ID
else a.REFERENCE end) REF_ID
from PARTS_TYPES a
start with a.ID in (select ID from PARTS_TYPES where ID_PARENT is NULL)
connect by prior
(case when a.REFERENCE is NULL
then a.ID
else a.REFERENCE end)=a.ID_PARENT

но этот вариант отпал, так как компонент TdxDBTreeView, который я использую, некорректно работает с одинаковыми значениями REF_ID у оригинального обьекта и ссылки, которые возвращает этот запрос. В моем случае TdxDBTreeView просто не отображает такую ссылку. Да и вообще говоря, в таком случае непонятно, к какому элементу дерева (к ссылке или к оригиналу) в этом запросе прикреплять сдублированные строки.

2) вариант с организацией дерева по фиктивному полю REF_ID_PARENT и дублированием дочерних элементов дерева

select a.*,
(select ID
from PARTS_TYPES
where REFERENCE = a.ID_PARENT) as REF_ID_PARENT
from PARTS_TYPES a
where ID_PARENT in
(select REFERENCE
from PARTS_TYPES
where REFERENCE is not NULL)
union
select b.*, b.ID_PARENT REF_ID_PARENT from PARTS_TYPES b


этот вариант тоже не проходит, т.к. в этом случае у дублируемых дочерних элементов дерева получаются одинаковые ID и TdxDBTreeView прикрепляет их к ссылке, но не прикрепляет ничего к настоящему родителю.

3) вариант с организацией дерева по фиктивным полям REF_ID и REF_ID_PARENT и дублированием дочерних элементов дерева

select a.*,
TO_CHAR(a.ID)||'_'||TO_CHAR((case when a.REFERENCE is NULL then a.ID else a.REFERENCE end)) REF_ID,
TO_CHAR(a.ID_PARENT)||'_'||TO_CHAR(a.ID_PARENT) REF_ID_PARENT
from PARTS_TYPES a
union
select a.*,
TO_CHAR((select ID from PARTS_TYPES where REFERENCE= a.ID_PARENT))||'_'||TO_CHAR(a.ID) REF_ID,
TO_CHAR((select ID from PARTS_TYPES where REFERENCE= a.ID_PARENT))||'_'||TO_CHAR(a.ID_PARENT) REF_ID_PARENT
from PARTS_TYPES a
start with ID_PARENT in
(select REFERENCE
from PARTS_TYPES
where REFERENCE is not NULL)
connect by prior ID=ID_PARENT

Но этот вариант нормально отображает только ссылки первого уровня.

Как выйти из такой ситуации? Или существуют другие пути решения этой проблемы?

Если нужна какая-то дополнительная информация -- скажите. Сильно не пинайте за такие неуклюжие запросы, я не претендую на опытного специалиста в SQL.
...
Рейтинг: 0 / 0
Аналог симлинков в дереве
    #32128495
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kak by eto skazt - zadacha ne iz priyatnyh poskolky
dannaya struktura teoreticheski NE DEREVO eto odin iz variantov
aciklicheskogo napravlennogo grafa. a grafy opisyvautsya drugoy
struturoy dannih:

create table nodes (
node_id number,
....
node_indo ...
);

create table node_links (
node_id number,
parent_id number
);

principialnaya raznica v tom chto :
dlya chisto derevyannoy slrukturi node_id - primary key a dlya
struktury opisannoy vishe primary key - eto para (node_id, parent_id)
pri kotoroy neobhodimost v ponyatii REF_ID otpadaet sama soboy.
...
Рейтинг: 0 / 0
Аналог симлинков в дереве
    #32129038
mitrich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ShgGena, а можно поподробнее? Что мне нужно заносить в эти таблицы? Каким запросом из этих таблиц получить нужную мне выборку?
...
Рейтинг: 0 / 0
Аналог симлинков в дереве
    #32129225
Chira
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT a.*, LEVEL
FROM
 (select ID,ID_PARENT, 'Original' OrRef
  from PARTS_TYPES
  UNION ALL
  SELECT REFERENCE,ID_PARENT, 'Reference'
  from PARTS_TYPES
  where REFERENCE is not NULL) a
START WITH ....
CONNECT BY ....
...
Рейтинг: 0 / 0
Аналог симлинков в дереве
    #32129722
mitrich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дык эта... connect by не работает с union
...
Рейтинг: 0 / 0
Аналог симлинков в дереве
    #32129748
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 mitrich: У сим-линков в юниксе есть одна мерзкая особенность -- потенциально бесконечная длина пути, если кто-то линкует на узел в той же ветви. Борются с этим просто -- ограничением максимальной длины ветви.

Так что, твой третий вариант не так уж и плох -- его с помощью copy/paste можно вытащить до произвольной, но фиксированной глубины вложенности.

Опять же, в юниксе, сим-линки пользуют как правило на каталоги (=узлы), а не на листья (=файлы). И методика борьбы достаточно тривиальная -- делается переход на дереференцированое имя каталога (bash исключение, но это его личная проблема).
Так что, может просто -- показывать сим-линки другой иконкой, и если клиент щёлкает на ней, то кидать его туда, куда этот линк указывает?

О, кстати, а если попытаться обнануть твой компонент и подсунуть ему вместо ID выражение типа nvl(REFERENCE,0)*max(ID)+ID ??? Правда как это сделать, так в лоб и не придумаешь...

А вообще, прав ShgGena -- это уже не дерево, а направленный граф. Причём насчёт ацикличности можно и поспорить (см. выше).
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Аналог симлинков в дереве
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]