Bei der Anwendung von Aktualisierungen eingreifen

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Datensätze aktualisieren


Wenn eine Client-Datenmenge ihre Aktualisierungen anwendet, legt der Provider fest, wie das Einfügen, Löschen und Ändern auf dem Datenbankserver oder in der Quelldatenmenge vorgenommen wird. Wenn Sie TClientDataSet mit einer externen Provider-Komponente verwenden, können Sie die Ereignisse und Methoden dieses Providers nutzen, um zu steuern, wie die Aktualisierungen angewendet werden. Diese sind unter Auf Aktualisierungsanforderungen des Client reagieren ausführlicher beschrieben.

Handelt es sich jedoch um einen internen Provider, wie es für alle mit einem Datenzugriffsmechanismus verknüpften Client-Datenmengen der Fall ist, können Sie seine Eigenschaften nicht setzen und auch keine Ereignisbehandlungsroutinen bereitstellen. Deshalb stellt die Client-Datenmenge eine Eigenschaft und zwei Ereignisse zur Verfügung, die es Ihnen ermöglichen, die Art und Weise zu beeinflussen, in der der interne Provider Änderungen vornimmt.

  • UpdateMode steuert, welche Felder in den SQL-Anweisungen, die der Provider für Aktualisierungen erzeugt, verwendet werden, um Datensätze zu finden. UpdateMode ist identisch mit der Eigenschaft UpdateMode des Providers. Weitere Informationen über die Eigenschaft UpdateMode des Providers finden Sie unter Die Art der Aktualisierung steuern.
  • Mithilfe von OnGetTableName können Sie dem Provider den Namen der Datenbanktabelle übergeben, auf die er die Aktualisierungen anwenden soll. Dadurch kann der Provider SQL-Anweisungen für Aktualisierungen erzeugen, wenn er aus der durch CommandText angegebenen Stored Procedure oder Abfrage den Datenbanknamen nicht ermitteln kann. Führt die Abfrage beispielsweise einen Join über mehrere Tabellen durch, für den nur Aktualisierungen an einer einzigen Tabelle erforderlich sind, ermöglicht die Bereitstellung einer Ereignisbehandlungsroutine für OnGetTableName dem internen Provider, die Aktualisierungen korrekt vorzunehmen. Die Ereignisbehandlungsroutine OnGetTableName verarbeitet drei Parameter: die interne Provider-Komponente, die interne Datenmenge, welche die Daten vom Server abgerufen hat, und einen Parameter, der den Tabellennamen zurückgibt, der in der erzeugten SQL-Anweisung verwendet werden soll.
  • BeforeUpdateRecord tritt für jeden Datensatz im Delta-Paket auf. Dieses Ereignis erlaubt es Ihnen, letzte Änderungen vorzunehmen, bevor der Datensatz eingefügt, gelöscht oder geändert wird. Außerdem bietet es eine Möglichkeit, Ihre eigenen SQL-Anweisungen auszuführen, um die Aktualisierung einzutragen, falls der Provider nicht die korrekte SQL erzeugen kann (wenn beispielsweise Verknüpfungen über mehrere Tabellen hinweg erfolgen, wobei mehrere Tabellen aktualisiert werden müssen). Die Ereignisbehandlungsroutine für BeforeUpdateRecord verarbeitet fünf Parameter: die interne Provider-Komponente, die interne Datenmenge, die Daten vom Server abgerufen hat, ein Delta-Paket, das auf den Datensatz positioniert ist, der aktualisiert werden soll, sowie einen Hinweis darauf, ob es sich bei der Aktualisierung um Einfügen, Löschen oder Ändern handelt, und einen Parameter, der zurückmeldet, ob die Ereignisbehandlungsroutine die Aktualisierung vorgenommen hat. Die Verwendung ist in der folgenden Ereignisbehandlungsroutine demonstriert. Der Einfachheit halber setzt das Beispiel voraus, dass die SQL-Anweisungen als globale Variablen zur Verfügung stehen, die nur Feldwerte benötigen:
procedure TForm1.SimpleDataSet1BeforeUpdateRecord(Sender: TObject;
   SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
   var Applied Boolean);
var
  SQL: string;
  Connection: TSQLConnection;
begin
  Connection := (SourceDS as TSimpleDataSet).Connection;
  case UpdateKind of
  ukModify:
    begin
     { 1. Datenmenge: aktualisiert Fields[1], verwendet Fields[0] in where-Klausel
      SQL := Format(UpdateStmt1, [DeltaDS.Fields[1].NewValue, DeltaDS.Fields[0].OldValue]);
      Connection.Execute(SQL, nil, nil);
     { 2. Datenmenge: aktualisiert Fields[2], verwendet Fields[3] in where-Klausel
      SQL := Format(UpdateStmt2, [DeltaDS.Fields[2].NewValue, DeltaDS.Fields[3].OldValue]);
      Connection.Execute(SQL, nil, nil);
    end;
  ukDelete:
    begin
     { 1. Datenmenge: verwendet Fields[0] in where-Klausel }
      SQL := Format(DeleteStmt1, [DeltaDS.Fields[0].OldValue]);
      Connection.Execute(SQL, nil, nil);
     { 2. Datenmenge: verwendet Fields[3] in where-Klausel }
      SQL := Format(DeleteStmt2, [DeltaDS.Fields[3].OldValue]);
      Connection.Execute(SQL, nil, nil);
    end;
  ukInsert:
    begin
     { 1. Datenmenge: Werte in Fields[0] und Fields[1] }
       SQL := Format(InsertStmt1, [DeltaDS.Fields[0].NewValue, DeltaDS.Fields[1].NewValue]);
      Connection.Execute(SQL, nil, nil);
     { 2. Datenmenge: Werte in Fields[2] und Fields[3] }
      SQL := Format(InsertStmt2, [DeltaDS.Fields[2].NewValue, DeltaDS.Fields[3].NewValue]);
      Connection.Execute(SQL, nil, nil);
    end;
  end;
  Applied := True;
end;
void __fastcall TForm1::SimpleDataSet1BeforeUpdateRecord(TObject *Sender,
   TDataSet *SourceDS, TCustomClientDataSet *DeltaDS, TUpdateKind UpdateKind, bool &Applied)
{
  TSQLConnection *pConn := (dynamic_cast<TSimpleDataSet *>(SourceDS)->Connection);
  char buffer[256];
  switch (UpdateKind)
  case ukModify:
    // 1. Datenmenge: aktualisiert Fields[1], verwendet Fields[0] in where-Klausel
    sprintf(buffer, UpdateStmt1, DeltaDS->Fields->Fields[1]->NewValue,
            DeltaDS->Fields->Fields[0]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    // 2. Datenmenge: aktualisiert Fields[2], verwendet Fields[3] in where-Klausel
    sprintf(buffer, UpdateStmt2, DeltaDS->Fields->Fields[2]->NewValue,
            DeltaDS->Fields->Fields[3]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    break;
  case ukDelete:
    // 1. Datenmenge: verwendet Fields[0] in where-Klausel
    sprintf(buffer, DeleteStmt1, DeltaDS->Fields->Fields[0]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    // 2. Datenmenge: verwendet Fields[3] in where-Klausel
    sprintf(buffer, DeleteStmt2, DeltaDS->Fields->Fields[3]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    break;
  case ukInsert:
    // 1. Datenmenge: Werte in Fields[0] und Fields[1]
    sprintf(buffer, UpdateStmt1, DeltaDS->Fields->Fields[0]->NewValue,
            DeltaDS->Fields->Fields[1]->NewValue);
    pConn->Execute(buffer, NULL, NULL);
    // 2. Datenmenge: Werte in Fields[2] und Fields[3]
    sprintf(buffer, UpdateStmt2, DeltaDS->Fields->Fields[2]->NewValue,
            DeltaDS->Fields->Fields[3]->NewValue);
    pConn->Execute(buffer, NULL, NULL);
    break;
}

Siehe auch