powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / update only modified fields
3 сообщений из 3, страница 1 из 1
update only modified fields
    #38599912
Gorynich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица мастер и несколько деталей со связями один-к-одному. Хочу редактировать несколько таблиц через один FIBPlus DataSet (работа через грид - требование клиента). Причем, важно чтобы запрос изменял только измененные поля, так как, одни и те же записи (но разные поля) часто меняются с разных клиентов. Если в execute block написать "обычные" update-ы для нескольких таблиц, то в update посылаются измененные и (что важно) кешированные значение клиентом. Кешированные данные могут быть устаревшими по отношению к изменениям других клиентов и могут затирать их изменения. Поэтому необходимо "update only modified fields". Изменять исходники FIB-ов не целесообразно, поскольку в execute block могут быть дополнительные условия для обновлений тех или иных таблиц деталей. Сейчас остановился на такой схеме:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
execute block (
  NEW_T1_FIELD_1 T1_TYPE_1 = :NEW_T1_FIELD_1,
  NEW_T1_FIELD_2 T1_TYPE_2 = :NEW_T1_FIELD_2,
  NEW_T1_FIELD_3 T1_TYPE_3 = :NEW_T1_FIELD_3,
  ...
  NEW_T1_FIELD_N T1_TYPE_N = :NEW_T1_FIELD_N,

  OLD_T1_FIELD_1 T1_TYPE_1 = :OLD_T1_FIELD_1,
  OLD_T1_FIELD_2 T1_TYPE_2 = :OLD_T1_FIELD_2,
  OLD_T1_FIELD_3 T1_TYPE_3 = :OLD_T1_FIELD_3,
  ...
  OLD_T1_FIELD_N T1_TYPE_N = :OLD_T1_FIELD_N,

  NEW_T2_FIELD_1 T2_TYPE_1 = :NEW_T2_FIELD_1,
  NEW_T2_FIELD_2 T2_TYPE_2 = :NEW_T2_FIELD_2,
  NEW_T2_FIELD_3 T2_TYPE_3 = :NEW_T2_FIELD_3,
  ...
  NEW_T2_FIELD_N T2_TYPE_N = :NEW_T2_FIELD_N,

  OLD_T2_FIELD_1 T2_TYPE_1 = :OLD_T2_FIELD_1,
  OLD_T2_FIELD_2 T2_TYPE_2 = :OLD_T2_FIELD_2,
  OLD_T2_FIELD_3 T2_TYPE_3 = :OLD_T2_FIELD_3,
  ...
  OLD_T2_FIELD_N T2_TYPE_N = :OLD_T2_FIELD_N,
...
   T3
...
   T4 
)
as
begin

  update TAB_1
  set
    T1_FIELD_1 TYPE_1 = iif(:NEW_T1_FIELD_1 is distinct from :OLD_T1_FIELD_1, :NEW_T1_FIELD_1, T1_FIELD_1),
    T1_FIELD_2 TYPE_2 = iif(:NEW_T1_FIELD_2 is distinct from :OLD_T1_FIELD_2, :NEW_T1_FIELD_2, T1_FIELD_2),
    T1_FIELD_3 TYPE_3 = iif(:NEW_T1_FIELD_3 is distinct from :OLD_T1_FIELD_3, :NEW_T1_FIELD_3, T1_FIELD_3),
    ...
    T1_FIELD_N TYPE_N = iif(:NEW_T1_FIELD_N is distinct from :OLD_T1_FIELD_N, :NEW_T1_FIELD_N, T1_FIELD_N),
  where
    (KEY_COND);

--  if () then
--  update or insert into
--  else 
--  delete
   
  update TAB_2
  set
    T2_FIELD_1 TYPE_1 = iif(:NEW_T2_FIELD_1 is distinct from :OLD_T2_FIELD_1, :NEW_T2_FIELD_1, T2_FIELD_1),
    T2_FIELD_2 TYPE_2 = iif(:NEW_T2_FIELD_2 is distinct from :OLD_T2_FIELD_2, :NEW_T2_FIELD_2, T2_FIELD_2),
    T2_FIELD_3 TYPE_3 = iif(:NEW_T2_FIELD_3 is distinct from :OLD_T2_FIELD_3, :NEW_T2_FIELD_3, T2_FIELD_3),
    ...
    T2_FIELD_N TYPE_N = iif(:NEW_T2_FIELD_N is distinct from :OLD_T2_FIELD_N, :NEW_T2_FIELD_N, T2_FIELD_N),
  where
    (KEY_COND);
  
  update TAB_3
  ...   

  update TAB_4
  ...   

end



Эта штука работает, но хотелось бы узнать - насколько это плохо?
...
Рейтинг: 0 / 0
update only modified fields
    #38599917
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gorynichхотелось бы узнать - насколько это плохо?
Нинасколько.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
update only modified fields
    #38604858
Фотография TPAKTOPA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Также как вариант, в BeforeEdit/BeforeInsert, сохранять прочитанные значения в структуру, как строка в БД
в BeforePost провярять, что редактировали и генерировать UpdateSQL динамически циклом
Так же можно ( если уместно) посылать только изменения, примерно
update table1 set Kol = Kol + :Difference

Разница с твоим примером - в одном случае работа делается на клиенте, в другом на сервере.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / update only modified fields
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]