RAD Studio |  |

Creating an OnUpdateRecord Event Handler
See Also
Collapse All

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:

Copy Code

    procedure TForm1.DataSetUpdateRecord(DataSet: TDataSet;
     UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
    begin
      { perform updates here... }
    end;

Copy Code

    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.
Copy Code

    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;

Copy Code

    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

Applying Cached Updates Using a Database

Applying Cached Updates with Dataset Component Methods

Handling Cached Update Errors

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!