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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.10.2013, 01:12
s.samoilenko s.samoilenko вне форума
Прохожий
 
Регистрация: 24.09.2013
Сообщения: 3
Версия Delphi: delphi 2005
Репутация: 10
Восклицание Сохранение данных по нескольким таблицам

Доброго времени суток.
Есть база данных Firebird.
Необходимо реализовать списание товаров со склада.
Делаю следующее.
1) создаю расходную накладную
2) заполняю ее данными из таблицы склада
3) выставляю необходимо количество товара для списания
4) жму сохранить и записи из dataSet вставляются в таблицу расходная накладная
5) со склада вычитается кол-во товара, указанное в dataSet
Проблема возникает со списанием товара со склада.

Как делаю.

Таблицы


Форма


Код:
FDataSet: TIBCustomDataSet;
ibQuery.cashedUpdate := true;



запрос для query
Код:
select ss.amount,
       ss.ID,
       ss.product_id,
       s.title
from sales_invoice ss
join storehouse s
    on s.id            = ss.product_id
    and ss.register_id = :idDocument
order by s.title

Последний вариант моего "мучения" был такой

Код:
procedure TForm1.Button2Click(Sender: TObject);
var Q: TIBQuery;
begin
  try
      IBTransactionWriteoffProducts.StartTransaction;
      if FDataSet.RecordCount = 0 then begin
          raise Exception.Create('Документ пуст!');
      end;

      Q := TIBQuery.Create(nil);
      Q.Transaction := IBTransactionWriteoffProducts;
      FDataSet.First;
	  while not FDataSet.Eof do begin
		  if(FDataSet.CachedUpdateStatus = cusInserted) then begin
			  Q.Close;
			  Q.SQL.Clear;
			  Q.SQL.Add('update storehouse set amount = amount - :amount where id = :id and amount - :amount >= 0');
			  Q.Prepare;
			  Q.ParamByName('id').AsInteger   := FDataSet.FieldByName('product_id').AsInteger;
			  Q.ParamByName('amount').AsFloat := FDataSet.FieldByName('amount').AsFloat;
			  Q.ExecSQL;

			  if(Q.RowsAffected < 1) then begin
				  raise Exception.Create('Вы пытаетесь списать товаров больше чем их есть на складе. Товар "'
										 + FDataSet.FieldByName('title').AsString + '" кол-во ' + FDataSet.FieldByName('amount').AsString);
			  end;
		  end;

		  FDataSet.Next;
	  end;


      FDataSet.Database.ApplyUpdates([FDataSet]);
      IBTransactionWriteoffProducts.Commit;
  except
      on E : Exception do begin
          IBTransactionWriteoffProducts.Rollback;
          ShowMessage(E.ClassName + ' ошибка : ' + E.Message);
      end;
  end;
end;
списание со склада проходит успешно, а вставка в расходную не происходит - ошибка транзакция уже активна.

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

Желательно используя стандартные компоненты.
Ответить с цитированием
  #2  
Старый 02.10.2013, 08:06
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Транзакция может быть открыта единожды.
Должно быть чето типа такого:
Код:
  StartTransaction;
  try
    blablabla // много кода
    CommitTransaction;
  except
    RollbackTransaction;
  end;
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 02.10.2013, 10:17
s.samoilenko s.samoilenko вне форума
Прохожий
 
Регистрация: 24.09.2013
Сообщения: 3
Версия Delphi: delphi 2005
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Транзакция может быть открыта единожды.
Должно быть чето типа такого:
Код:
  StartTransaction;
  try
    blablabla // много кода
    CommitTransaction;
  except
    RollbackTransaction;
  end;
Спасибо, это я знаю. Знаете как помочь - напишите.
Ответить с цитированием
  #4  
Старый 03.10.2013, 10:31
s.samoilenko s.samoilenko вне форума
Прохожий
 
Регистрация: 24.09.2013
Сообщения: 3
Версия Delphi: delphi 2005
Репутация: 10
По умолчанию

Все спасибо. Решено.
Нада было проверить на

if not IBTransactionWriteoffProducts.inTransaction then IBTransactionWriteoffProducts.Start;
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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