Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Внешние ключи в контекст транзации. [D7, IB 7.1]


Страницы:   1 2

Девушка ©   (2005-09-18 23:03:00) 

Хочу в одной транзации добавить сначала добавить запись в родительскую таблицу (справочник), потом, без commit-а добавить запись в дочернюю таблицу в которой в связанном посредством внешнего ключа поле ссылается на еще не подтвержденную родительскую запись.
Выдается ошибка Foreign Key.
Транзакция настроена на ReadCommited.
Добавление записей происходит из DBGridEH, а справочники прописаны как LookUp-поля.

Как добавить запись?

Пример:
Есть таблица товаров и таблица приходов.
1. Стартанули транзакцию.
2. Добавили новый товар "Конфеты".
3. Добавили новый приход с товаром "Конфеты" (здесь возникает ошибка)
4. Либо подтвердили, либо откатили всю транзацию.


Девушка   (2005-09-19 14:18:00) [21]


> Если речь идет о добавлении нового документа с двумя или
> более уровнями (фактурами), то имхо, следует разделять заголовок
> и "дочки".

OK. Если разделять, то достаточно ли будет прописать commit в AfterPost датасета?


msguns   (2005-09-19 12:48:00) [22]

Если речь идет о добавлении нового документа с двумя или более уровнями (фактурами), то имхо, следует разделять заголовок и "дочки".
Т.е. сначала юзер добавляет заголовок, он фиксируется в БД (короткая пишущая транзакция) и потом можно добавлять записи-дочки, подтвержение которых можно делать отдельными транзакциями либо "скопом" опять-же короткими пишущими транзакциями.
Какой путь выбрать - Вам виднее. Я бы советовал итти позаписным путем применительно к складу. Правда при этом придется ввести понятие "проведенный-непроведенный) документ, но это только добавить надежности и достоверности Вашим данным.

Какими копонентами работать - Вам виднее. Можно редактировать через грид (многие считают этот способ кульно-рульным), а можно использовать модальные формы с подтверждением вставки-изменения каждой записи.
Однако надо помнить, что объект TIBDataset сам делает подтверждение - откат транзакций (что требует от клиента доп.затрат на перехват разных BeforePost+AfterPost во избежании "фокусов" при "гуляющей" коррекции в гриде) и не дает такое 100 процентно контролируемое управление со стороны клиента, как пара TIBQuery+TIBSQL


Sergey13   (2005-09-19 12:15:00) [23]

2[12] Девушка ©   (19.09.05 12:06)
Я такие вещи иногда делаю так.
На отдельной форме кидаем нужные Едиты и грид если нужно. Грид призываю к отдельному датасету (я "люблю" RxMemoryData) с нужной структурой. При нажатии на "сохранить" делаю все как в [8], но через основные датасеты. И волки целы и овцы сыты.
Можно делать и так как ты. Но комитить каждое действие. Если по логике работы это допустимо, то в принципе ничего страшного.


Андрей Жук   (2005-09-19 12:07:00) [24]

Можешь использовать ХП


Девушка   (2005-09-19 12:06:00) [25]


> Это невозможно.

В смысле не явно посылать команды а работать через IBDataset.Insert IBDataset.post и т.п.


Sergey13   (2005-09-19 11:20:00) [26]

2[10] Девушка ©   (19.09.05 11:17)
>Хотелось бы добавления средствами грида, а не ХП или SQL комманд.
Это невозможно.


Девушка   (2005-09-19 11:17:00) [27]

Справочник товаров был приведен лишь для примера т.к. является классикой. Реальная задача другая.

> Обе таблици, главная и подчиненная, должны использовать
> одну транзакцию

Так оно и есть. ReadCommeted


> msguns ©   (19.09.05 10:14) [8]

Если писать с помощью другой транзакции, транзакцию с которой связан датасет дочерней таблицы нужно будет изменить? Хотелось бы добавления средствами грида, а не ХП или SQL комманд.


ANB   (2005-09-19 10:21:00) [28]

Присоединяюсь к мнению msguns и вопрос автору сабжа :
А зачем весь огород в этой задаче ? Справочник товаров - штука более менее постоянная, туда новый товар нужно добавлять ручками пользователя и уж никак не локапом выбирать (т.к. потом придет идея построить дерево и т.п.)

Другой вопрос, если ты ведешь учет остатков и вот тогда изменения в таблице остатков должны согласовываться с добавлением в таблицу проводок и/или строк документов. Как это сделать - написал msguns.


msguns   (2005-09-19 10:14:00) [29]

Чтоб не было ситуации, описанной в [7] (долгая пишущая транзакция), надо разделять чтение и запись. Т.е. запись в справочник и добавление к нему в дочернюю таблицу данных о движении (приходе) должны выполнять в отдельнойзаписывающей транзакции.
Делается это так:
1. На клиенте получаем обе записи (мастер и детал, деталов может быть несколько, например, если работаем через стрингрид или CDS)
2. Стартуем на сервере новую пишущуютранзакцию
3. Определяем новый ID товара, "дернув" соотв. генератор
4. Записываем в справочник, используя явно полученный ID (п.3)
5. Записываем в детал, используя в качестве ключа связки тот же ID (п.3)
6. Подтверждаем транзакцию
7. Переоткрываем основные НД и заполняем (если есть) визуализирующие контролы (стрингрид, CDS,..)
8. Позиционируем осн. таблицу на ID (п.3), активируя таким образом только что добавленный товар.

ЗЫ. Из сабжа сделал вывод о том, что БД учета товаров построена по-любительски, без отражения в ней реальных объектов-документов.

ЗЫ2. Нельзя жестко связывать добавление в справочники с добавлением в БД оперативной информации. Можно серьезно оконфузиться ;)))


Sergey13   (2005-09-19 09:29:00) [30]

2Девушка ©   (18.09.05 23:03)
Как то у тебя все неправильно. 8-)
1.Если где то между 2 и 4 пунктами узер уйдет чай пить то транзакция будет висеть неограниченно долго. А она и так у тебя очень долгая.
2.Получать ИДшник родителя можно (и лучше) ДОвставки.
3.Лукап поля на здоровые справочники (а справочник товаров наверное немаленький) не есть хорошо, ИМХО.


Johnmen   (2005-09-19 09:29:00) [31]

>посредством внешнего ключа поле ссылается на еще не подтвержденную родительскую запись.

Это (подтвержденная или нет) не имеет значения.
Ошибка - неверный ссылочный ключ при новом приходе. Другого быть не может.


Ярослав   (2005-09-19 07:41:00) [32]

На серваке он есть, даже если транзакция не поттверждена!
Обе таблици, главная и подчиненная, должны использовать одну транзакцию


Ильш   (2005-09-19 06:11:00) [33]

в поле датасета виден
а на серваке его еще нет т.к. транзакция еще открыта


Девушка   (2005-09-18 23:12:00) [34]

Код - в смысле, id-к


Девушка   (2005-09-18 23:11:00) [35]


> видимо, для новой записи справочника на клиент не  получен
> код, необходимый для занесения в дочернюю таблцу

Код получен. При трассировке в поле датасета дочерней таблице он виден и выбирается правильно.


Desdechado   (2005-09-18 23:04:00) [36]

видимо, для новой записи справочника на клиент не  получен код, необходимый для занесения в дочернюю таблцу


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо