There are two events that let you handle errors that occur during the update process:
- During the update process, the internal provider generates an OnUpdateError event every time it encounters an update that it can't handle. If you correct the problem in an OnUpdateError event handler, then the error does not count toward the maximum number of errors passed to the ApplyUpdates method. This event only occurs for client datasets that use an internal provider. If you are using TClientDataSet, you can use the provider component's OnUpdateError event instead.
- After the entire update operation is finished, the client dataset generates an OnReconcileError event for every record that the provider could not apply to the database server.
You should always code an
OnReconcileError or
OnUpdateError event handler, even if only to discard the records returned that could not be applied. The event handlers for these two events work the same way. They include the following parameters:
DataSet: A client dataset that contains the updated record which couldn't be applied. You can use this dataset's methods to get information about the problem record and to edit the record in order to correct any problems. In particular, you will want to use the CurValue, OldValue, and NewValue properties of the fields in the current record to determine the cause of the update problem. However, you must not call any client dataset methods that change the current record in your event handler.
E: An object that represents the problem that occurred. You can use this exception to extract an error message or to determine the cause of the update error.
UpdateKind: The type of update that generated the error. UpdateKind can be ukModify (the problem occurred updating an existing record that was modified), ukInsert (the problem occurred inserting a new record), or ukDelete (the problem occurred deleting an existing record).
Action: A var parameter that indicates what action to take when the event handler exits. In your event handler, you set this parameter to
- Skip this record, leaving it in the change log. (rrSkip or raSkip)
- Stop the entire reconcile operation. (rrAbort or raAbort)
- Merge the modification that failed into the corresponding record from the server. (rrMerge or raMerge) This only works if the server record does not include any changes to fields modified in the client dataset's record.
- Replace the current update in the change log with the value of the record in the event handler, which has presumably been corrected. (rrApply or raCorrect)
- Ignore the error completely. (rrIgnore) This possibility only exists in the OnUpdateError event handler, and is intended for the case where the event handler applies the update back to the database server. The updated record is removed from the change log and merged into Data, as if the provider had applied the update.
- Back out the changes for this record on the client dataset, reverting to the originally provided values. (raCancel) This possibility only exists in the OnReconcileError event handler.
- Update the current record value to match the record on the server. (raRefresh) This possibility only exists in the OnReconcileError event handler.
The following code shows an
OnReconcileError event handler that uses the reconcile error dialog from the RecError unit which ships in the objrepos directory. (To use this dialog, add RecError to your uses clause.)
procedure TForm1.ClientDataSetReconcileError(DataSet: TCustomClientDataSet; E: EReconcileError; UpdateKind: TUpdateKind, var Action TReconcileAction);
begin
Action := HandleReconcileError(DataSet, UpdateKind, E);
end;
void __fastcall TForm1::ClientDataSetReconcileError(TCustomClientDataSet *DataSet,
EReconcileError *E, TUpdateKind UpdateKind, TReconcileAction &Action)
{
Action = HandleReconcileError(this, DataSet, UpdateKind, E);
}