Конференция "Начинающим" » Не работает DataSet.Refresh, или можно ли обойтись без CloseOpen?
 
  • TheEd (26.06.15 15:32) [0]
    Уважаемые мастера!
    Есть компонент A (TpFIBDataSet), у которого SelectSQL такой:
    SELECT
       A.*, B.ASUM
    FROM TABLE_A A
     LEFT JOIN
       (select AID, sum(SUMFIELD) as ASUM from TABLE_B group by AID) B
     ON B.AID=A.ID
    WHERE
     <некоторое условие отбора>


    Как Вы поняли - A - мастер, B - деталь. Соответственно в мастере поле ASUM должно отображать сумму по полю SUMFIELD у детали.
    Если в детали поменялись записи в этом поле, для обновления пробовал делать A.Refresh - не работает. Помогает A.CloseOpen(true), но он переоткрывает детальную таблицу, что нежелательно...
     Как сделать полю рефреш без его переоткрытия и, соответственно без переоткрытия детали?
    зы: у А есть SQLs.RefresSQL.Text:
     
    SELECT * FROM TABLE_A WHERE  TABLE_A.ID = :OLD_ID

  • кгшзх © (26.06.15 16:10) [1]
    рефреш работает,

    но он не видит изменений внесенных другой транзакцией пока живет в той транзакции, с которой его открыли.

    и еще тут нет никакого мастер-дитейла. это ты с прямым углом перепутал
  • TheEd (26.06.15 16:23) [2]

    > тут нет никакого мастер-дитейла

    есть. он тут
    <некоторое условие отбора>

    прячется если считать A подчиненным, а если мастером - то для таблицы TABLE_B это реализовано в компоненте B :)

    а по поводу транзакций - они "быстрые", их 2 на чтение и запись. Т.о. как только внесли изменение, транзакция записи должна завершиться... Если после этого делаем рефреш - транзакция новая должна открыться и прочитать данные, или я что-то путаю?
  • кгшзх © (26.06.15 16:25) [3]
    снова читай [1]
  • sniknik © (26.06.15 17:22) [4]
    > или я что-то путаю?
    да, это не "мастер-детайл", это простое объединение в запросе.
  • TheEd (29.06.15 09:47) [5]

    > да, это не "мастер-детайл", это простое объединение в запросе.

    да я про другое! Джоин в запросе - это одно. Просто есть другой запрос, связанный с данным, правильнее сказать - набор данных, и он - дочерний! Он меняет своё поле, от которого зависит то что прилепит к каждой строке join - а именно, сумму по некоторому полю у всех дочерних записей.
     Вот его то и надо обновить.
     Поскольку собаку на управлении транзакциями я ещё не съел, понимаю только в общих чертах, то конкретизирую детали проекта:
     1. работаю через FIBPlus. Есть 2 транзакции - на чтение и на запись:
    taRead:
    write
    isc_tpb_nowait
    read_committed
    rec_version
    TARollback
    tpbReadCommitted
    taWrite:
    CurrentParametrs (пусто)
    TARollback
    tpbReadCommitted


    обращения к данным - через TpFIBDataSet'ы
    как обновить набор данных без переоткрытия, ели join уже не тот...?
  • кгшзх © (29.06.15 11:32) [6]
    1. тебе по-русски сказали "здесь нету мастердитейл"
    2. переоткрытие датасета здесь вообще не при чем.
    читающую транзакцию надо завершить, и начать новую.

    датасет при этом умрет гарантированно.
  • TheEd (29.06.15 14:00) [7]
    1. ладно, не спорю, хотя мы о разных вещах говорим, но в данном случае это не имеет отношения к делу. Поменять данные можно откуда угодно.
    2.

    читающую транзакцию надо завершить, и начать новую.
    датасет при этом умрет гарантированно.

    А зачем тогда Refresh, если датасет умрёт при открытии новой транзакции?
  • кгшзх © (29.06.15 14:22) [8]
    у жирафа нерв, который инеррвирует гортань имеет длину несколько метров.
    расстояние от жирафьего мозга до гортани ~ 20 см.

    почему и зачем?
    потому что первые жирафы были рыбами.
    а у рыб мозг, жабры и сердце очень близко.
    поэтому топология прокладки нерва была такая, что нерв выходил из мозга, огибал артерию у сердца и втыкался в жабры.

    когда рыбы вышли на сушу и стали жирафами ничего не поменялось.
    нерв выходит из мозга, спускается по шее до сердца, огибает артерию, и поднимается обратно к гортани.

    потому что так унаследовано.
  • TheEd (30.06.15 10:17) [9]
    Спасибо за доходчивое объяснение :)
    Тем не менее, жираф мог бы воспользоваться override для оптимизации своего нерва :)))
    Я в принципе обошел ситуацию немного кривовато, но работает: когда в подчинённой таблице меняются данные, от которых изменятся данные в указанном запросе, сохраняю ID всех текущих записей, делаю по цепочку CloseOpen и восстанавливаю позиции. Выглядит без особых мерцаний, как если бы рефреш без переоткрытия сработал...
  • Барбара (01.07.15 15:26) [10]
    >жираф мог бы воспользоваться override для оптимизации своего нерва

    Принцип Лисков говорит, что так делать неправильно. Хотя, принцип Лисков вряд ли применим к биологии. Впрочем, и к программированию тоже.
 
Конференция "Начинающим" » Не работает DataSet.Refresh, или можно ли обойтись без CloseOpen?
Есть новые Нет новых   [119244   +4][b:0][p:0.001]