-
Понадобилось перенести приложение из-под оракла под 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? -
Jack128_ (09.02.09 11:10) [1]что делает connect by prior ?? В FB такого нет.
+ параметры в FB предворяются двоеточием where group_id = :P_BEGINGROUP -
Процедуру придется писть рекурсивную.
-
Виталий Панасенко (09.02.09 12:26) [3]
> Jack128_ (09.02.09 11:10) [1]
> + параметры в FB предворяются двоеточием where group_id
> = :P_BEGINGROUP
Странно... В при работе через БДЕ/АДО - тоже двоеточие используется для указания параметров.. -
Виталий Панасенко (09.02.09 12:28) [4]
> Sergey13 © (09.02.09 11:14) [2]
>
> Процедуру придется писть рекурсивную.
А можно EXECUTE BLOCK -
Jack128_ (09.02.09 13:22) [5]
> Странно... В при работе через БДЕ/АДО - тоже двоеточие используется
> для указания параметров..
угу. Походу в оракле это принято иначе.. Ну там и null = '' так что ничего удивительного... -
А версию сервера слабо указать ?
Вот для 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 однозначно. -
Труп Васи Доброго © (09.02.09 14:00) [7]можно вообще обойтись без навороченных запросов :) поставь тригер, который будет делать нужный апдейт у потомков и тебе нужно будет всего лишь обновить одну головную запись. Остальное добьёт тригер. ИМХО это более правильный подход для каскадного апдейта.
-
Проблема ещё в том, что сам по себе такой селект тоже будет нужен.
FIBPlus имеется.
Количество групп не превышает ста. -
StriderMan (10.02.09 16:47) [9]
> Но на использование IBX в клиентском приложении придется забить
почему это? TIBScript схавает и не такое -
YurikGL © (12.02.09 20:18) [10]В таких случаях в FB всегда без проблем использовал рекурсивные хранимки.