![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с древовидными данными в FB [FB]
keymaster © (2009-02-09 11:04:00)Понадобилось перенести приложение из-под оракла под fb.
Есть древовидный справочник (группы записей)
и есть сами записи.
Под ораклом их апдейт делался так:
update
[......]
where
[....]
and (groups.group_id in (select groups.group_id
from groups start with group_id = P_BEGINGROUP
connect by prior group_id = parentgroup_id ))
т.е. задавался параметр p_begingroup и обновлялись только те записи, которые относятся к нужной группе или её дочерним группам.
Можно ли такое провернуть в FB?
(2009-03-22 13:38:00) [1]Удалено модератором
(2009-03-22 13:38:00) [2]Удалено модератором
YurikGL (2009-02-12 20:18:00) [3]В таких случаях в FB всегда без проблем использовал рекурсивные хранимки.
StriderMan (2009-02-10 16:47:00) [4]
> Но на использование IBX в клиентском приложении придется забить
почему это? TIBScriptсхавает и не такое
keymaster (2009-02-09 15:07:00) [5]Проблема ещё в том, что сам по себе такой селект тоже будет нужен.
FIBPlus имеется.
Количество групп не превышает ста.
Труп Васи Доброго (2009-02-09 14:00:00) [6]можно вообще обойтись без навороченных запросов :) поставь тригер, который будет делать нужный апдейт у потомков и тебе нужно будет всего лишь обновить одну головную запись. Остальное добьёт тригер. ИМХО это более правильный подход для каскадного апдейта.
PEAKTOP (2009-02-09 13:43:00) [7]А версию сервера слабо указать ?
Вот для 2.1 и выше.
UPDATE MYTABLE T1 SET
T1.SOMEFILED = '<VALUE>'
WHERE (T1.GROUP_ID IN (WITH RECURSIVE STMT AS (
SELECT TB1.ID, TB2.PARENT_ID FROM TREE_TABLE TB1 WHERE (TB1.PARENT_ID = '<VALUE>')
UNION ALL
SELECT TB2.ID, TB2.PARENT_ID FROM TREE_TABLE TB2, STMT TB3 WHERE (TB2.PARENT_ID = TB2.ID)
)SELECT TREE.ID FROM STMT TREE)
)
Только лично я бы не стал использовать IN в виду его тормознутости. Парсер его превратит в список условий OR()OR()OR()OR(), что даст на нормальном объеме в 1 000 000 записей несколько часов работы такого оператора.
Гораздо быстрее будет через EXECUTE BLOCK
EXECUTE BLOCK (
Q_NEW_VALUE VARCHAR(10)
,Q_PARENT_GROUP_ID INT
)AS
DECLARE VARIABLE P_GROUP_IDS BLOB SUB_TYPE 1 SEGMENT SIZE 80;
BEGIN
-- Получаем список ID групп с учетом вложенности.
WITH RECURSIVE STMT AS (
SELECT TB1.ID, TB2.PARENT_ID FROM TREE_TABLE TB1 WHERE (TB1.PARENT_ID = :Q_PARENT_GROUP_ID)
UNION ALL
SELECT TB2.ID, TB2.PARENT_ID FROM TREE_TABLE TB2, STMT TB3 WHERE (TB2.PARENT_ID = TB2.ID)
)SELECT '~' || LIST(TREE.ID, '~') || '~' FROM STMT TREE INTO :P_GROUP_IDS;
-- Обновляем набор данных
UPDATE MYTABLE T1 SET
T1.SOMEFILED = :Q_NEW_VALUE
WHERE (:P_GROUP_IDS containing '~'||T1.GROUP_ID||'~');
END
Второй способ дает выигрыш в скорости в разы в геометрической прогресии. Но на использование IBX в клиентском приложении придется забить. FIBPlus или AnyDAC однозначно.
Jack128_ (2009-02-09 13:22:00) [8]
> Странно... В при работе через БДЕ/АДО - тоже двоеточие используется
> для указания параметров..
угу. Походу в оракле это принято иначе.. Ну там и null = '' так что ничего удивительного...
Виталий Панасенко (2009-02-09 12:28:00) [9]
> Sergey13 © (09.02.09 11:14) [2]
>
> Процедуру придется писть рекурсивную.
А можно EXECUTE BLOCK
Виталий Панасенко (2009-02-09 12:26:00) [10]
> Jack128_ (09.02.09 11:10) [1]
> + параметры в FB предворяются двоеточием where group_id
> = :P_BEGINGROUP
Странно... В при работе через БДЕ/АДО - тоже двоеточие используется для указания параметров..
Sergey13 (2009-02-09 11:14:00) [11]Процедуру придется писть рекурсивную.
Jack128_ (2009-02-09 11:10:00) [12]что делает connect by prior ?? В FB такого нет.
+ параметры в FB предворяются двоеточием where group_id = :P_BEGINGROUP