О навигации по дочерним объектам.

Здесь обсуждаем систему TDM/PDM/Workflow Lotsia PDM PLUS (PartY PLUS).
Ответить
Vlsl
Новый участник
Сообщения: 5
Зарегистрирован: 11 апр 2008, 15:27
Откуда: МОКБ Марс

О навигации по дочерним объектам.

Сообщение Vlsl »

Мы так и не нашли рациональный способ перебора ВСЕХ дочерних объектов без их принудительной нумерации (и записи их кол-ва в родительский объект(при вводе).

Есть ли более рациональный способ?
Тот, который мы используем, - прводит к большим сложностям при корректировках
(напр., при удалении дочернего объекта, надо все оставшиеся ПЕРЕНУМЕРОВЫВАТЬ и пересчитывать).

Можно ли как-то управлять системной переменной a_TLinkID (текущий код связи)?

Никто не озадачивался ничем подобным ... ?
Аватара пользователя
Старик Крупский
Активный участник
Сообщения: 803
Зарегистрирован: 27 июл 2006, 22:17
Откуда: Москва

Сообщение Старик Крупский »

В документации (в практических рекомендациях) есть пара примеров перебора дочерних объектов.
Управлять a_TlinkID не пробовал, а зачем? В чем суть?
"Лучше меньше, да лучше" (C)
Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Самый рациональный способ перебора дочерних объектов - использовать функцию f_ExecSQLSelect.
С помощью запроса получить идентификаторы дочерних объектов
и обработать.
Аватара пользователя
Alexey
Активный участник
Сообщения: 123
Зарегистрирован: 21 окт 2005, 15:49
Откуда: Белоруссия, Минск
Контактная информация:

Сообщение Alexey »

хех не знаю в тему или нет..., но вот только что наваял SQL скриптец который отбирает все без исключения дочерние объекты, не зависимо от уровня вложенности по типу связи дерево проекта... в качестве параметра ид родителя и погнали.... если надо то обращайтесь... выложу на сайтец
- А деньги?
- Какие деньги? - сказал Остап, открывая дверь. - Вы, кажется, спросили про какие-то деньги?
----------------------------------
SEO стало интересным
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

а действительно - зачем перебирать все дочерние объекты, даже не так, зачем знать сколько их. В чем суть? (СК) :wink:

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Суть в минимизации затрат для посика - у меня есть все идентификаторы определенной ветки дерева в которой я хочю найти
нужную мне карточку. то-ли искать во всей базе то-ли в нескольуих объектах.

А если вы например хотите поменять атрибут, который распределен на
все дерево, например проект. В дереве много проектов, а мне допустим нужно поменять атрибут в определенном. Для этого я беру
все идентификаторы и обрабатываю. Зачем? Ну конечно подборка это просто необходимый инструмент для пользователя! ;)
А у меня пользователь меняет нужные атрибуты запуском просто действия! :)
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

мы к счастью не сталкивались с подобной проблемой :wink: (один раз меняли атрибут у 10 тысяч объектов через расширенный импорт на своем SQL и все) :wink: но все таки мне кажется - может структуру данных проще подкорректировать и хранить общие значения проекта в некотором служебном объекте имея на него прямые ссылки из дочерних карточек - тогда будет достаточно менять всего один атрибут у одного объекта для всего проекта...

ps
возвращаясь к теме - мне кажется что связь должна быть в обратную сторону т.е. не родитель должен знать свои дочерние объекты а дочерние объекты должны знать своего родителя. Кстати эта проблема постоянно всплывает - как хранить массивы - и мы всегда делаем дочерние объекты и не думаем ни о чем :wink:

т.е. в каждый дочерний объект записать прямой адрес родителя - и делать выборки из базы именно по этому атрибуту, да и вообще у нас каждый объект содержит до 10 служебных адресных атрибутов - которые практически делают поиск неактуальным т.к. есть прямые адреса :wink:

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

А теперь представь, что у тебя в базе всего 808170 карточек и на эти
карточки навешенно всего 10796063 атрибутов.

Ты все еще уверен, что в поиске нет необходимости? :)
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Сообщение Александр »

Вопрос исчерпан :wink: :wink: :wink:

ps
я думал это начало пути... а тут жизнь уже в самом разгаре! :wink:
pps
Конечно - поиск нужен, и этот поиск а точнее его быстродействие и последующая обработка - каждую ночь снится нам в кошмарных снах о SQL

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Anderyt
Активный участник
Сообщения: 777
Зарегистрирован: 15 июл 2004, 13:15
Используемое ПО: Lotsia PDM PLUS
Откуда: Тюмень
Контактная информация:

Сообщение Anderyt »

2 Alexey
было бы очень любопытно посмотреть на этот скрипт. если все еще не жалко - выложите его плиз...
заранее спасибо!
(там что то с рекурсией, да?..)
лучше день потерять, потом за пять минут долететь!
Аватара пользователя
Alexey
Активный участник
Сообщения: 123
Зарегистрирован: 21 окт 2005, 15:49
Откуда: Белоруссия, Минск
Контактная информация:

Сообщение Alexey »

Ну вот сама хранимая процедура перебора всех дочерних объектов не зависимо от уровня вложенности:

Как использовать результаты отобранные данной процедурой думаю писать не надо... ну если надо то напишу, единственный нюанс, не забудьте после всех операций в действиях сделать drop table
-- =============================================
-- Процедура поиска всех потомков объекта
-- по значению ИД родителя
-- независимо от вложенности
-- по связи = Дерево проектов [1]
-- =============================================
CREATE PROCEDURE itc2mix_FindAllChildren
@idParent numeric, -- Создаем входную переменную idParent
@strShifr varchar (2000) -- Входная строка со значение шифра
AS
begin

declare @cicIdParent numeric -- создается переменная idParent для цикла

-- =============================================
-- Проверка на существование таблицы, если существует
-- то удаляем
-- =============================================
/* IF OBJECT_ID('tempdb..##itc2mix_allChildren') IS NOT NULL
begin
DROP TABLE ##itc2mix_allChildren
end
*/
-- =============================================
-- Создаем темповую таблицу с названием #itc2mix_allChildren, если она не создана
-- =============================================
IF OBJECT_ID('tempdb..##itc2mix_allChildren') IS NULL
begin
CREATE TABLE ##itc2mix_allChildren
(
t_idParent numeric NULL,
t_Checked bit NOT NULL,
t_strShifr varchar(2000)
)
end
-- =============================================
-- Таблица создана
-- =============================================

-- =============================================
-- Заполняем ее первыми вхождениями на основе переданного IdParent
-- =============================================
INSERT
INTO ##itc2mix_allChildren
SELECT o_r.id, 0, @strShifr
FROM
LSDBO.object_reference_view O_R,
lsdbo.tree_link_view tl
WHERE
tl.parent_id = @idParent
and
tl.link_id =o_r.id
and
tl.link_type_id = 1
-- =============================================
-- Вызываем функцию просмотра таблицы
-- =============================================

-- =============================================
-- Цикл заполнения таблицы данными при проходе по всем объектам
-- =============================================

WHILE (
select max(t_idParent)
from
##itc2mix_allChildren
where t_Checked = 0
) is NOT NULL
-- обработка while
begin
-- присваеваем значение переменноей вызова @cicIdParent
Select
@cicIdParent = max(t_idParent)
from ##itc2mix_allChildren
where t_Checked = 0
-- конец присвоения
-- вставка новых найденных значений в таблицу
INSERT
INTO
##itc2mix_allChildren
SELECT o_r.id, 0, @strShifr
FROM
LSDBO.object_reference_view O_R,
lsdbo.tree_link_view tl
WHERE
tl.parent_id = @cicIdParent -- переменная подаваемая на вход цикла
and
tl.link_id =o_r.id
and
tl.link_type_id = 1
-- конец вставки новых найденных значений в таблицу

-- устанавливаем значение переменной как отработанное дабы не попадать в бесконечный цикл
UPDATE ##itc2mix_allChildren
SET t_Checked = 1
WHERE t_idParent = @cicIdParent;

end
-- конец обработки while

-- Просмотр результирующей таблицы
--select * from #itc2mix_allChildren
-- =============================================
-- Убиваем созданную таблицу
-- =============================================
--drop TABLE #itc2mix_allChildren


end
GO
Некоторые комментарии... так как во время работы данной ХП происходит создание временной глобальной таблицы, аргумент шифр используется для исключения пересечения, было бы все здорово если бы можно было использовать локальную временную таблицу, но увы тогда данные не доступны для обработки. Если что не понятно пишите объясню...
- А деньги?
- Какие деньги? - сказал Остап, открывая дверь. - Вы, кажется, спросили про какие-то деньги?
----------------------------------
SEO стало интересным
Юрий
Активный участник
Сообщения: 239
Зарегистрирован: 13 янв 2005, 14:30
Используемое ПО: Lotsia PDM PLUS LT
Откуда: Украина, Донецк
Контактная информация:

Сообщение Юрий »

Есть вариант проще! :)

Вот хранимая функция которую можно использовать в запросе
и которая возвращает список всех дочерних объектов:

Код: Выделить всё

CREATE FUNCTION [LSDBO].[rec2_object_level]
(
	@obj_id numeric(18,0)
)
RETURNS @rez table  
(
id numeric(18,0),
flag_my char(1),
level int
)
AS
BEGIN

declare @lev int
select @lev=1

insert into @rez (id, flag_my, level) values (@obj_id,'N',@lev)

while (select count(*) from (select * from @rez where flag_my='N') tree 
 left join LSDBO.tree_link tree1 on tree.id=tree1.parent_id and
 tree1.link_filial_id in (1) where tree1.id is not null)>0
begin
select @lev=@lev+1
insert into @rez (id, flag_my, level) 
select tree1.link_id, null flag_my, @lev level
from (select * from @rez where flag_my='N') tree 
left join LSDBO.tree_link tree1 on tree.id=tree1.parent_id and
 tree1.link_filial_id in (1) where tree1.id is not null

update @rez set flag_my='R' where flag_my='N'
update @rez set flag_my='N' where flag_my is null

end

	RETURN 
END
Ответить