Creating an OnUpdateRecord Event Handler

From RAD Studio
Jump to: navigation, search

Go Up to Using the BDE to cache updates Index

Note: The Borland Database Engine (BDE) has been deprecated, so it will not be enhanced. For instance, BDE will never have Unicode support. You should not undertake new development with BDE. Consider migrating your existing database applications from BDE to dbExpress. For information about migrating from BDE to dbExpress, see http://www.embarcadero.com/rad-in-action/migration-upgrade-center.

When a BDE-enabled dataset applies its cached updates, it iterates through the changes recorded in its cache, attempting to apply them to the corresponding records in the base table. As the update for each changed, deleted, or newly inserted record is about to be applied, the dataset component's OnUpdateRecord event fires.

Providing a handler for the OnUpdateRecord event allows you to perform actions just before the current record's update is actually applied. Such actions can include special data validation, updating other tables, special parameter substitution, or executing multiple update objects. A handler for the OnUpdateRecord event affords you greater control over the update process.

Here is the skeleton code for an OnUpdateRecord event handler:

 procedure TForm1.DataSetUpdateRecord(DataSet: TDataSet;
  UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
 begin
   { perform updates here... }
 end;
 void __fastcall TForm1::DataSetUpdateRecord(TDataSet *DataSet,
   TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
 {
   // Perform updates here...
 }

The DataSet parameter specifies the cached dataset with updates.

The UpdateKind parameter indicates the type of update that needs to be performed for the current record. Values for UpdateKind are ukModify, ukInsert, and ukDelete. If you are using an update object, you need to pass this parameter to the update object when applying the update. You may also need to inspect this parameter if your handler performs any special processing based on the kind of update.

The UpdateAction parameter indicates whether you applied the update. Values for UpdateAction are uaFail (the default), uaAbort, uaSkip, uaRetry, uaApplied. If your event handler successfully applies the update, change this parameter to uaApplied before exiting. If you decide not to update the current record, change the value to uaSkip to preserve unapplied changes in the cache. If you do not change the value for UpdateAction, the entire update operation for the dataset is aborted and an exception is raised. You can suppress the error message (raising a silent exception) by changing UpdateAction to uaAbort.

In addition to these parameters, you will typically want to make use of the OldValue and NewValue properties for the field component associated with the current record. OldValue gives the original field value that was fetched from the database. It can be useful in locating the database record to update. NewValue is the edited value in the update you are trying to apply.

Warning: An OnUpdateRecord event handler, like an OnUpdateError or OnCalcFields event handler, should never call any methods that change the current record in a dataset.

The following example illustrates how to use these parameters and properties. It uses a TTable component named UpdateTable to apply updates. In practice, it is easier to use an update object, but using a table illustrates the possibilities more clearly.

 procedure TForm1.EmpAuditUpdateRecord(DataSet: TDataSet;
   UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
 begin
   if UpdateKind = ukInsert then
     UpdateTable.AppendRecord([DataSet.Fields[0].NewValue, DataSet.Fields[1].NewValue])
   else
     if UpdateTable.Locate('KeyField', VarToStr(DataSet.Fields[1].OldValue), []) then
       case UpdateKind of
         ukModify:
           begin
             UpdateTable.Edit;
             UpdateTable.Fields[1].AsString := VarToStr(DataSet.Fields[1].NewValue);
             UpdateTable.Post;
           end;
         ukInsert:
           begin
             UpdateTable.Insert;
             UpdateTable.Fields[1].AsString := VarToStr(DataSet.Fields[1].NewValue);
             UpdateTable.Post;
           end;
         ukDelete: UpdateTable.Delete;
       end;
         UpdateAction := uaApplied;
 end;
 void __fastcall TForm1::EmpAuditUpdateRecord(TDataSet *DataSet,
   TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
 {
   if (UpdateKind == ukInsert)
   {
     TVarRec values[2];
     for (int i = 0; i < 2; i++)
       values[i] = DataSet->Fields->Fields[i]->NewValue;
     UpdateTable->AppendRecord(values, 1);
   }
   else
   {
     TLocateOptions lo;
     lo.Clear();
     if (UpdateTable->Locate("KeyField", DataSet->Fields->Fields[0]->OldValue, lo))
       switch (UpdateKind)
       {
         case ukModify:
           UpdateTable->Edit();
           UpdateTable->Fields->Fields[1]->Value = DataSet->Fields->Fields[1]->Value;
           UpdateTable->Post();
           break;
         case ukDelete:
           UpdateTable->Delete();
           break;
       }
   }
   UpdateAction = uaApplied;
 }

See Also

Code Examples