Использование FireDac для обновления только 1 дублирующейся строки (без первичного ключа или уникального поля) - PullRequest
1 голос
/ 20 июня 2019

У меня есть старое приложение, которое я поддерживаю и которое использует базу данных Microsoft Access. Оригинальный дизайн таблицы не добавлял первичные ключи к каждой таблице. Я работаю над программой миграции, которая помимо прочего добавляет и заполняет новое поле первичного ключа (GUID), когда это необходимо.

Это происходит в три этапа:

  1. Добавить новое поле guid без ограничений
  2. Заполните поле новыми уникальными направляющими
  3. Добавить ограничения первичного ключа

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

  Query.SQL.Add('SELECT * FROM ' + TableName);
  Query.Open;

  while Query.Eof = false do
  begin
    Query.Edit;
    Query.FieldByName(NewPrimaryKeyFieldName).AsGuid := TGuid.NewGuid;
    Query.Post;

    Query.Next;
  end;

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

FireDac правильно выдает сообщение об ошибке

Update command updated [2] instead of [1] record.  

Я могу открыть базу данных в Access и удалить дублирующиеся записи или назначить им уникальную направляющую, отредактировав таблицу. Я хотел бы, чтобы мой инструмент конвертации сделал это автоматически.

Есть ли какой-нибудь способ работы с этими дублирующимися строками в FireDac? Либо обновить по одному, либо удалить только один из них?

1 Ответ

2 голосов
/ 21 июня 2019

По моему мнению, нет способа сделать это только с одним оператором SQL.

Я бы сделал это: 1. Скопируйте всю таблицу без дубликатов, используя новую временную таблицу

SELECT DISTINCT * FROM <TABLENAME>
Добавить ключи Удалить старое содержимое таблицы и скопировать новое содержимое из новой таблицы

Примечания:

База данных должна бытьнедоступно для всех остальных для этой операции 2. Сделайте BACKUP до

...