Добавление записей в связные таблицы на трехзвенке

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
atg
Сообщения: 6
Зарегистрирован: 18 апр 2005, 17:56

Добавление записей в связные таблицы на трехзвенке

Сообщение atg » 22 май 2005, 12:13

расскажите, пожалуйста, кто как решает следующую проблему.
Есть например 2 таблицы:
table first
id_first // primary
data..

table second
id_second // primary
id_first // foreign на таблицу first
data..

Есть трехзвенка.
на клиенте (в ClientDataSet'ax нужно создать запись в таблицу first и в таблицу second (причем она должна быть связана с вновь созданой записью из first).
Происходить это должно в одной транзакции.
Проблема в том, что при добавлении клиент не знает еще id_first и поэтому связать записи не может.

Есть вариант создать на сервере пустую свзяку first-second, сделать refresh на клиенте, и потом просто редактировать ее.

Может есть еще варианты?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 22 май 2005, 14:21

Проблема в том, что при добавлении клиент не знает еще id_first и поэтому связать записи не может.
нет такой проблемы. при добавлении клиент ДОЛЖЕН знать id_first. То же самое, как и с генераторами. Сначала надо СОЗДАТЬ (или получить) идентификатор, а потом вставлять записи.

p.s. неужели не очевидно?

atg
Сообщения: 6
Зарегистрирован: 18 апр 2005, 17:56

Сообщение atg » 22 май 2005, 17:54

p.s. неужели не очевидно?
да очевидно.
вопрос в другом. какие есть _удобные_ методы получения значения id заранее? На сервере все просто: FIBDataSet.AutoUpdateOptions. Но на трехзвенку на клиента это не проходит.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 23 май 2005, 13:01

Лично я при работе в трёхзвенке для вставки новых записей в мастер-детальных отношениях (и не только) генерирую на клиенте временный ID для вставляемых записей и связываю по нему на клиенте же. Держу также локальный признак "новая", "изменённая", "удалённая" Сохраняю пачками, пишу на аппсервере процедуру, которая стартует и рестартует сколько мне надо транзакций, передаю ей команды и данные в виде WideString, в который складываю на клиенте изменения сеанса при инизиализации режима "сохранить". На сервере, соответсвенно, симметричный парсер командной строки. Не уверен, что сейчас по техническому состоянию интструмента это оптимальный путь, но когда я начинал с MIDAS в конце прошлого века, в его собственных механизмах было столько дыр и глюков, что пришлось наворачивать поверх него эту технологию. Я к ней привык, она работает и удобна (мне) поэтому за развитием сосбственно MIDAS я больше не слежу.

Brambrulet
Сообщения: 9
Зарегистрирован: 10 ноя 2004, 22:33

Re: Добавление записей в связные таблицы на трехзвенке

Сообщение Brambrulet » 23 май 2005, 14:39

atg писал(а):Есть вариант создать на сервере пустую свзяку first-second, сделать refresh на клиенте, и потом просто редактировать ее.
А если клиентов несколько, то как они решат какая из пар чья?

2 kdv
С генераторами тоже не очень просто. Несколько вызовов Gen_ID подряд могут запросто вернуть одинаковые значения.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: Добавление записей в связные таблицы на трехзвенке

Сообщение Merlin » 23 май 2005, 14:45

Brambrulet писал(а): С генераторами тоже не очень просто. Несколько вызовов Gen_ID подряд могут запросто вернуть одинаковые значения.
А мужики-то не знают (С). Пример в студию пжалста.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 23 май 2005, 14:51

Несколько вызовов Gen_ID подряд могут запросто вернуть одинаковые значения.
ну-ну. сейчас начнется цирк с select gen_id(a, 0) + 1 from ... или еще чем то вроде.

Brambrulet
Сообщения: 9
Зарегистрирован: 10 ноя 2004, 22:33

Сообщение Brambrulet » 23 май 2005, 15:07

Да нет одинаковый результат иногда возвращают несколько вызовов gen_id(a, 1). О вероятности подобного, кстати говоря, и в документации сказано.

Конкретный пример, где напоролся на подобное поведение, сейчас не вспомню - было это год или два назад. Скорее всего была ХП, которая возвращала несколько последовательных значений генератора.

MuirsheenDurkin
Сообщения: 44
Зарегистрирован: 21 янв 2005, 10:18

Сообщение MuirsheenDurkin » 23 май 2005, 15:19

Brambrulet писал(а):Конкретный пример .. сейчас не вспомню
"Гнилая отмазка на конкретную предъяву" (с)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 23 май 2005, 15:25

Brambrulet писал(а):Да нет одинаковый результат иногда возвращают несколько вызовов gen_id(a, 1). О вероятности подобного, кстати говоря, и в документации сказано.
Перстом укажи плиз.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 23 май 2005, 16:00

Да нет одинаковый результат иногда возвращают несколько вызовов gen_id(a, 1). О вероятности подобного, кстати говоря, и в документации сказано.
откровенный и бессовестный гон. единственный случай, когда можно было получить тот же самый номер, это

- gen_id(a, 1)
- сервер или железо падает. причем страница генераторов не успевает сохраниться
- старт сервера
- gen_id(a, 1) - продолжается выдача с сохраненных номеров.

Это все понятно ситуация нештатная, сродни повреждению БД, но вот чтобы 2 gen_id(a, 1) выдали 2 одинаковых значения при непрерывной работе сервера - это никогда.

atg
Сообщения: 6
Зарегистрирован: 18 апр 2005, 17:56

Сообщение atg » 23 май 2005, 17:27

Merlin писал(а): Держу также локальный признак "новая", "изменённая", "удалённая" Сохраняю пачками, пишу на аппсервере процедуру, которая стартует и рестартует сколько мне надо транзакций, передаю ей команды
"новая", "изменённая", "удалённая" и есть команды?
Не уверен, что сейчас по техническому состоянию интструмента это оптимальный путь, но когда я начинал с MIDAS в конце прошлого века, в его собственных механизмах было столько дыр и глюков
а какие собственные технологии подобного были у Мидаса?

Блин, идея интересная.. но неужели ничего за столько лет Borland более удобного не придумали :)

atg
Сообщения: 6
Зарегистрирован: 18 апр 2005, 17:56

Re: Добавление записей в связные таблицы на трехзвенке

Сообщение atg » 23 май 2005, 17:30

Brambrulet писал(а):А если клиентов несколько, то как они решат какая из пар чья?
да по сути также возращать клиенту id новых записей.. хотя это по сути тоже самое, что просто получить их на сервере (без добавления) и передать клиенту

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 23 май 2005, 18:12

atg писал(а):
Merlin писал(а): Держу также локальный признак "новая", "изменённая", "удалённая" Сохраняю пачками, пишу на аппсервере процедуру, которая стартует и рестартует сколько мне надо транзакций, передаю ей команды
"новая", "изменённая", "удалённая" и есть команды?

Сначала - calc поле в серверном (апп-) TIBQuery, которое на кленте делаю data и устанавливаю на всех Before... соответсвенно действию. Delete привожу к Edit - Piznak='D', Post, на ClientDataSet наложен фильтр по Priznak<>'D'. При формировании пакета изменений - да, становятся командами внутри строки, после команды идут значения полей.
atg писал(а): а какие собственные технологии подобного были у Мидаса?
Собственно, ApplyUpdates-Reconcile. Но криво это и неудобно, разбираться с конфликтами на клиенте. Ещё CommandText, но это не секурно, да и вообще, не клиентово имхо дело транзакциями управлять. Отдал серверу данные, а как с ними бороться - в методе сервера обычно решается куда эффективнее, если возможные конфликты логики не требуют вмешательства юзера, а, скажем состоят в полностью автоматизируемой обработке лок-конфликтов (не всегда допустимо).

Anton Glasunov
Сообщения: 31
Зарегистрирован: 26 окт 2004, 15:18

Сообщение Anton Glasunov » 25 май 2005, 21:16

Ещё CommandText, но это не секурно, да и вообще, не клиентово имхо дело транзакциями управлять
Использование CommandText не ведет с неизбежностью к управлению транзакциями на клиенте. Можно, к примеру, пользоваться событиями TDataSetProvider'а на сервере.

И сейчас, вполне, можно пользоваться MIDASом, за исключением, возможно, каскадных Master-Detail через ТDataSetField, мне не удалось их заставить работать так, как мне хочется.

А так работает несколько лет, функциональность приложений наращиваем как-то, может привыкли. Трезвенка позволила нам обойтись без терминальных серверов в головном офисе для филиалов, работающих на 64-256К каналах.


По текущей теме - использую апп-серверную функцию, что-то вроде:

function TMyAppServer.GetNewGenID(const AGeneratorName: String): Integer;

И вызываю, по потребности.

Ответить