Конференция "Базы" » Работа с древовидными данными в FB [FB]
 
  • keymaster © (09.02.09 11:04) [0]
    Понадобилось перенести приложение из-под оракла под 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
  • Sergey13 © (09.02.09 11:14) [2]
    Процедуру придется писть рекурсивную.
  • Виталий Панасенко (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 = ''  так что ничего удивительного...
  • PEAKTOP © (09.02.09 13:43) [6]
    А версию сервера слабо указать ?

    Вот для 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]
    можно вообще обойтись без навороченных запросов :) поставь тригер, который будет делать нужный апдейт у потомков и тебе нужно будет всего лишь обновить одну головную запись. Остальное добьёт тригер. ИМХО это более правильный подход для каскадного апдейта.
  • keymaster © (09.02.09 15:07) [8]
    Проблема ещё в том, что сам по себе такой селект тоже будет нужен.
    FIBPlus имеется.
    Количество групп не превышает ста.
  • StriderMan (10.02.09 16:47) [9]

    > Но на использование IBX в клиентском приложении придется забить

    почему это? TIBScript схавает и не такое
  • YurikGL © (12.02.09 20:18) [10]
    В таких случаях в FB всегда без проблем использовал рекурсивные хранимки.
 
Конференция "Базы" » Работа с древовидными данными в FB [FB]
Есть новые Нет новых   [134477   +43][b:0][p:0.001]