Ошибка TClientDataset ApplyUpdates из-за ограничения таблицы базы данных
У меня есть старое приложение Delphi 7, которое загружает данные из одной таблицы базы данных, выполняет много операций и вычислений и, наконец, записывает записи в таблицу назначения.
Это старое приложение вызывает ApplyUpdates каждые 500 записей по причинам производительности.
Проблема в том, что иногда в этой куче записей лежит та, которая вызывает ограничение базы данных; Delphi запускает исключение на ApplyUpdates.
Моя проблема в том, что я не знаю, какая запись ответственна за это исключение. Есть 500 кандидатов!
Можно ли спросить TClientDataset, какая запись является оскорбительной?
Я не хочу, чтобы ApplyUpdates foreach добавлял записи для проблем со скоростью.
2 ответа
Я думаю, что вы можете попытаться реализовать OnReconcileError
событие, которое запускается один раз для каждой записи, которая не может быть применена к набору данных. Поэтому я бы попробовал следующий код, raSkip
означает здесь, чтобы пропустить текущую запись:
procedure TForm1.ClientDataSet1ReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction);
begin
Action := raSkip;
ShowMessage('The record with ID = ' + DataSet.FieldByName('ID').AsString +
' couldn''t be updated!' + sLineBreak + E.Context);
end;
Но, пожалуйста, обратите внимание, я никогда не пробовал это раньше, и я не уверен, что еще не слишком поздно игнорировать ошибки, вызванные ApplyUpdates
функция. Забыл упомянуть, попробуйте использовать переданный параметр DataSet
который должен содержать запись, которая не может быть обновлена; это может быть способ определить, какая запись вызвала проблему.
А также here
описаны обновления, применяющие рабочий процесс.
Внедрение OnReconcileError
предоставит вам доступ к записи и данным, которые ответственны за исключение. Легко сделать это, добавив "Диалог устранения ошибок". Он находится в диалоговом окне "Новые элементы", которое отображается File | Новый | Другой. После того, как вы добавили его в свой проект и использовали его в форме с набором данных клиента. Следующий код показывает, как он вызывается.
procedure TForm1.ClientDataSetReconcileError(DataSet: TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind;
var Action: TReconcileAction);
begin
Action := HandleReconcileError(DataSet, UpdateKind, E);
end;
Он будет отображаться вместо диалога исключений. Это позволит вам просмотреть оскорбительные данные и выбрать, как вы хотите продолжить. Прошло более 5 лет с тех пор, как я последний раз пользовался им, надеюсь, я не забыл некоторые детали.