Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 01.09.2013, 21:38
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию Несколько записей в DBGrid и отмена изменений

Как отобразить несколько записей в DBGrid (для полльзователя), но оставить за собой право разом отменить все изменения (т.е. что-то вроде Table.Cancel; )

Идея такая: формируется документ, к котором привязывается несколько позиций товара. (сам документ хранится в одной таблице, а привязанные к документу товары в другой)

Перед тем, как занести этот документ в БД пользователю выводится конечное окно, где он проверяет правильность введённых данных. И одним из пунктов является DBGrid, в котором отображаются товары. Но как добавить несколько я не знаю. А писать процедуры на добавление\удаление не хочется (ибо подозреваю, что и не надо, есть обходной путь)
Ответить с цитированием
  #2  
Старый 02.09.2013, 00:54
Аватар для Yurk@
Yurk@ Yurk@ вне форума
Специалист
 
Регистрация: 07.09.2007
Адрес: Украина, г. Днепропетровск
Сообщения: 892
Версия Delphi: 7 + ОгнеПтица
Репутация: выкл
По умолчанию

смотри в сторону кеширования изменений или управления транзакциями
__________________
Поживу - увижу, Доживу - узнаю, Выживу - учту.
[P.S.]->Выражая благодарность за помощь - Вы получаете шанс на помощь в следующий раз
Ответить с цитированием
  #3  
Старый 02.09.2013, 08:52
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,051
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Yurk@
смотри в сторону кеширования изменений или управления транзакциями

Еще TMemoryTable.
Вся подготовка делается в таблице в памяти, потом, если пользователь подтвердил, копируется в БД.
Ответить с цитированием
  #4  
Старый 02.09.2013, 09:36
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

На самом деле, если использовать нормальные компоненты, то в них должно быть встроенное свойство CachedUpdates и ApplyUpdates/CancelUpdates. Какая БД используется?
Ответить с цитированием
  #5  
Старый 02.09.2013, 11:04
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Цитата:
Сообщение от Freeman
CachedUpdates и ApplyUpdates/CancelUpdates. Какая БД используется?

Используется MySQL + ADO.
Я почитаю про ApplyUpdates/CancelUpdates, спасибо.

Перевёл таблицу в режим ltBatchOptimistic.

Пишу:

Код:
  with fDataModule.tItems do
  begin
    Insert;
    FieldByName('Item').AsString := item;
    FieldByName('Weight').AsFloat := weight;
    FieldByName('InsertWeight').AsFloat := iweight;
    FieldByName('MetallWeight').AsFloat := weight - iweight;
    Post;
  end;

В момент Insert начинает ругаться на то, что DataSet закрыт. Я догадываюсь, что ltBatchOptimistic блокирует insert. Как в этом случае правильно вносить изменения в таблицы?
Решено после перевода таблицы в режим ltBatchOptimistic забыл открыть таблицу.

Последний раз редактировалось Uniq!, 02.09.2013 в 20:05.
Ответить с цитированием
  #6  
Старый 02.09.2013, 17:32
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Код:
ADOQuery1.UpdateBatch(arAll);
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #7  
Старый 02.09.2013, 20:12
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Страдалецъ, это всё уже прочитано.

Нужно решение для такой задачи: есть мастер таблица (документ), к которому привязываются из дэтэйл таблицы изделия.

Код:
мастер.UpdateBatch(arAll);

В поле ID, которе является AI (auto increment), ничего не записывается.
Соответственно в дэтэйл таблицу записать изделия не могу, т.к. туда нужен этот ID номер.

Без "быдлокода" как это реализовать?

Задача скорее всего сведётся к нахождению последнего значения Столбца ID. и добавления к нему 1цы

Последний раз редактировалось Uniq!, 02.09.2013 в 21:14.
Ответить с цитированием
  #8  
Старый 03.09.2013, 05:04
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Uniq!
Задача скорее всего сведётся к нахождению последнего значения Столбца ID. и добавления к нему 1цы
Это и будет быдлокод.

А на самом деле нужно в рамках одной транзакции записать значение мастер-записи на сервер, получить значение ID (не знаю, как это делается в ADO, к сожалению), прописать его всем подчиненным записям и вызвать UpdateBatch.

Как понимаю, пакетный режим должен быть включен для подчиненного набора данных, а на мастере -- наоборот, все изменения происходят у одной записи, курсор БД стоит на месте, для тиражирования ID достаточно читать его значение -- это и будет значение ID текущей записи.
Ответить с цитированием
  #9  
Старый 03.09.2013, 10:53
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Цитата:
Сообщение от Freeman
получить значение ID
Код:
Master.UpdateBatch;
// использовать filterGroup, Для фильтрации только "новых" данных?
//т.к. запись может быть не одна: нужно пробежаться по всем новым запися, while not Detail.EOF ??
Detail.FieldByName('TicketID').AsInteger := Master.FieldDyName('ID').AsIntger;
Detail.UpdateBatch;

Цитата:
Сообщение от Freeman
Как понимаю, пакетный режим должен быть включен для подчиненного набора данных, а на мастере -- наоборот
Вот эту часть не понял совсем.

Хотите сказать
Код:
Master.LockType := ltOptimistic;
Но тогда документ будет попадать в БД без возможность отмены действий. Или я чего-то не понимаю.

Ещё мне неясны слова
Цитата:
Сообщение от Freeman
нужно в рамках одной транзакции
Что это значит?

BD в папке release (просто откомпилировать в release и всё само заведётся)

Обе таблицы (tMaster и tDetail находятся в режиме ltLockBatchOptimistic )
Собственно, что писать в коде кнопки @Сохранить изменения и какие дополнительные манипуляции необходимо произвести?

Проблема в том, что:
Код:
tDetail.MasterSource := dsDetail;

После того как
Код:
tMaster.UpdateBatch;
записи в Master присваивается ID, и Detail теряет связь, с Master, потому что у Detail записей в колнке 'MasterID' ничего ещё нет.

Нужен дополнительный tDetail_Temp, который не связан по MasterSource ?? и использовать его как временное хранилище? =\ попахивает "быдлокодом"
Вложения
Тип файла: rar TestBD.rar (120.6 Кбайт, 13 просмотров)

Последний раз редактировалось Uniq!, 03.09.2013 в 12:58.
Ответить с цитированием
  #10  
Старый 03.09.2013, 15:28
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Я не работал с ADO, поэтому конкретно по его режимам подсказать не могу. Возможно, для корректной работы master-detail нужно временно присваивать добавленной мастер-записи код -1, который копировать в AfterInsert в подчиненные, а после получения актуального кода обновлять все отрицательные записи.

Вообще же, если делать ввод накладных по учебнику, должно быть так:
  • В главной форме выводится грид, соответствующий списку накладных.
  • Создается диалог ввода/редактирования накладной, работающей с текущей записью из списка главной формы. Простым полям накладной соответствуют DBEdit-ы и DBComboBox-ы, а подчиненные данные вводятся в гриде или нескольких гридах на вкладках.
  • По нажатию "OK" все скопом сохраняется, по нажатию "Отмена" все скопом отменяется.
Тогда получается, что при входе в диалог набор данных главной формы находится в режиме вставки или редактирования, а при выходе из диалога делается Post или Cancel. Подчиненные наборы данных отрабатываются событиями.

Вспомнил, что уже отвечал на похожую тему на другом форуме.

Последний раз редактировалось Freeman, 03.09.2013 в 15:33.
Ответить с цитированием
  #11  
Старый 03.09.2013, 16:11
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Ощущение, что это очередные костыли, не отпускает меня.
Но они прочнее моих текущих))

Как отфильтровать/перебрать все отрицательные Detail записи?
я уже выдвигал предположения по поводу цикла или Filter =...

Последний раз редактировалось Uniq!, 03.09.2013 в 16:23.
Ответить с цитированием
  #12  
Старый 03.09.2013, 16:36
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Uniq!
Ощущение, что это очередные костыли, не отпускает меня.
Я честно скачал приложенный проект и попытался сделать то, что предлагаю, но понял, что начинаю писать программу за кого-то другого.

Цитата:
Сообщение от Uniq!
Как отфильтровать/перебрать все отрицательные Detail записи?
А как реализовано отношение "мастер-подчиненный" в компонентах ADO? Об этом должно быть написано в справке.
Ответить с цитированием
  #13  
Старый 03.09.2013, 20:20
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Зарубежные коллеги вот что мне подсказали:

Что, если возникла особая нужда иметь доступ к ID, то надо исключать ADO. Он статичен... ... this way we dont use ado. Я не вникал.

Что посоветовали:
Код:
ADOCommand.CommandText := 'SET :new_id = LAST_INSERT_ID()+1;'
ADOCommand.Parameters[0].DataType := ftInteger;
ADOCommand.Parameters[0].Direction := pdOutput;

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

Только не могу понять в каком из параметров ADOCommand лежит ответ
Ответить с цитированием
  #14  
Старый 03.09.2013, 20:53
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Использование last_insert_id типично для веб-проектов, а в клиент-серверных системах считается если не совсем быдлокодом, то транзакционно небезопасным -- это точно. Хотя, если MySQL используется, у него транзакции через известное место.

Короче, на таком уровне уже советую почитать какую-нибудь серьезную литературу по проектированию и реализации клиент-серверных приложений как со стороны Delphi и DB-компонентов, так и со стороны сервера.
Ответить с цитированием
Этот пользователь сказал Спасибо Freeman за это полезное сообщение:
Uniq! (03.09.2013)
  #15  
Старый 03.09.2013, 21:09
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Посоветуйте книгу, серьёзную на таком уровне, пожалуйста

Я реализовал, но мне не нравится
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 14:55.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter