Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Устранение проблемы с автоинкрементом в Delphi XE3 при работе с базами данных MySQL 5.6 в режиме транзакций

Delphi , Базы данных , SQL

При работе с базами данных в режиме транзакций важно, чтобы все изменения в связанных таблицах были применены корректно. Проблема, с которой столкнулся пользователь, заключается в том, что при использовании компонентов Zeos 7.0.4 в среде Delphi XE3 для сохранения данных в таблицы с мастера-детали связью, автоинкрементное поле в таблице мастера не заполняется значением, которое необходимо для установки связи с детальной таблицей.

Оригинальный код пользователя:

ZQPerson.Append;
ZQEmployee.Append;
try
  ZQPersonName.Value := Edit1.Text;
  ZQPerson.ApplyUpdates; // Здесь ожидалось получить автоинкрементное значение, но возвращается 0
  ZQEmployeePersonID.Value := ZQPersonId.Value; // Ссылка на запись мастера
  ZQEmployeeRegNo.Value := StrToInt(Edit2.Text);
  ZQEmployee.ApplyUpdates;
  ZConnection1.Commit; // Зафиксировать обе таблицы в одной транзакции
except
  ZQPerson.CancelUpdates;
  ZQEmployee.CancelUpdates;
  ZConnection1.Rollback; // При исключениях откатить все изменения
  raise;
end;
ZQPerson.CommitUpdates;
ZQEmployee.CommitUpdates;

Запись из ZSQLMonitor:

2013-08-29 00:01:23 cat: Execute, proto: mysql-5, msg: INSERT INTO person (Id, name) VALUES (NULL, 'Edit1') --> Это после ZQPerson.ApplyUpdates
2013-08-29 00:01:50 cat: Execute, proto: mysql-5, msg: INSERT INTO employee (Id, RegNo, ProductId) VALUES (NULL, 1000, 0), errcode: 1452, error: Cannot add or update a child row: a foreign key constraint fails (`test`.`employee`, CONSTRAINT `FK_A6085E0491BDF8EE` FOREIGN KEY (`PersonId`) REFERENCES `person` (`Id`) --> Это после ZQEmployee.ApplyUpdates
2013-08-29 00:02:05 cat: Execute, proto: mysql-5, msg: Native Rollback call --> Откат после исключения на ZQEmployee.ApplyUpdates

Решение проблемы:

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

function LastInsertID(ATableName: string): Integer;
var DBQuery: TZQuery;
begin
  DBQuery := TZQuery.Create(Self);
  with DBQuery do
  begin
    Connection := ZConnection1;
    SQL.Clear;
    SQL.Add('Select Last_Insert_ID() as Last_Insert_ID from ' + ATableName);
    Open;
    Result := FieldByName('Last_Insert_ID').Value;
    Free;
  end;
end;

procedure Persist;
var LastID: Integer;
begin
  ZQPerson.Append;
  ZQEmployee.Append;
  try
    ZQPersonName.Value := Edit1.Text;
    ZQPerson.ApplyUpdates; // Здесь ожидалось автоинкрементное значение
    LastID := LastInsertID('Person'); // Получение последнего автоинкрементного значения
    ZQEmployeePersonID.Value := LastID; // Установка связи с записью мастера
    ZQEmployeeRegNo.Value := StrToInt(Edit2.Text);
    ZQEmployee.ApplyUpdates;
    ZConnection1.Commit; // Фиксация транзакции
  except
    ZQPerson.CancelUpdates;
    ZQEmployee.CancelUpdates;
    ZConnection1.Rollback; // Откат транзакции при исключениях
    raise;
  end;
  ZQPerson.CommitUpdates;
  ZQEmployee.CommitUpdates;
end;

Альтернативный подход:

Для начала транзакции необходимо использовать метод StartTransaction компонента ZConnection. После применения обновлений к мастеру, необходимо обновить данные в ZQuery, чтобы получить новое автоинкрементное значение.

ZConnection1.StartTransaction;
ZQPerson.ApplyUpdates; // Применение обновлений к мастеру
ZQPerson.Refresh; // Обновление данных в ZQuery
ZQEmployeePersonID.Value := ZQPersonId.Value; // Получение автоинкрементного значения из поля Id
// Продолжение работы с детальной таблицей...
ZConnection1.Commit; // Фиксация транзакции

Заключение:

При работе с транзакциями важно правильно управлять состоянием транзакции и корректно обрабатывать автоинкрементные поля в базах данных. Использование функции Last_Insert_ID() или обновление данных в ZQuery после применения обновлений к мастеру позволяет решить проблему, описанную пользователем.

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: SQL ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 13:44:55/0.0053019523620605/1