Intervention pendant l'application des mises à jour

De RAD Studio
Aller à : navigation, rechercher

Remonter à Mise à jour des enregistrements


Lorsqu'un ensemble de données client applique ses mises à jour, le fournisseur détermine comment gérer l'écriture des insertions, des suppressions et des modifications sur le serveur de la base de données ou dans l'ensemble de données source. Lorsque vous utilisez TClientDataSet avec un composant fournisseur externe, vous pouvez utiliser les propriétés et les événements de ce fournisseur pour agir sur la façon dont sont appliquées les mises à jour. Ces méthodes sont décrites dans Comment répondre aux demandes de mise à jour des clients.

Mais, lorsque le fournisseur est interne, ce qui se passe pour tout ensemble de données client associé à un mécanisme d'accès aux données, vous ne pouvez pas définir ses propriétés ni fournir de gestionnaire d'événement. Il s'ensuit que l'ensemble de données client publie une propriété et deux événements vous permettant d'agir sur la façon dont le fournisseur interne applique les mises à jour.

  • UpdateMode détermine les champs utilisés pour rechercher des enregistrements dans les instructions SQL que génère le fournisseur pour appliquer les mises à jour. UpdateMode est identique à la propriété UpdateMode du fournisseur. Pour plus d'informations sur la propriété UpdateMode du fournisseur, voir Comment contrôler l'application des mises à jour.
  • DBLocal.OnGetTableName qui vous permet de fournir au fournisseur le nom de la table de base de données à laquelle il doit appliquer les mises à jour. Cela permet au fournisseur de générer les instructions SQL de mise à jour lorsqu'il ne peut pas identifier la table de la base de données à partir de la procédure stockée ou de la requête spécifiée par CommandText. Par exemple, si la requête exécute une jointure multitable qui n'implique des mises à jour que pour une seule table, la fourniture d'un gestionnaire d'événement OnGetTableName permet au fournisseur interne d'appliquer correctement les mises à jour. Le gestionnaire d'événement OnGetTableName reçoit trois paramètres : le composant fournisseur interne, l'ensemble de données interne ayant extrait les données du serveur, et un paramètre pour renvoyer le nom de la table à utiliser dans le SQL généré.
  • DBLocal.BeforeUpdateRecord, qui se produit pour chaque enregistrement du paquet delta. Cet événement permet d'effectuer tout changement de dernière minute avant que l'enregistrement ne soit inséré, supprimé ou modifié. En outre, il vous permet d'exécuter vos propres instructions SQL pour appliquer la mise à jour lorsque le fournisseur n'est pas en mesure de générer une instruction SQL correcte (c'est par exemple le cas des jointures multitables dans lesquelles plusieurs tables doivent être mises à jour.) Le gestionnaire d'événement BeforeUpdateRecord reçoit cinq paramètres : le composant fournisseur interne, l'ensemble de données interne qui a extrait les données du serveur, un paquet delta positionné sur l'enregistrement qui va être mis à jour, une indication de la nature de la mise à jour (insertion, suppression ou modification), et un paramètre qui renvoie l'indication que le gestionnaire d'événement a effectué la mise à jour. Tout cela est illustré dans le gestionnaire d'événement suivant. Pour simplifier, cet exemple suppose que les instructions SQL sont accessibles en tant que variables globales ne nécessitant que les valeurs des champs :
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
     { 1st dataset: update Fields[1], use Fields[0] in where clause }
      SQL := Format(UpdateStmt1, [DeltaDS.Fields[1].NewValue, DeltaDS.Fields[0].OldValue]);
      Connection.Execute(SQL, nil, nil);
     { 2nd dataset: update Fields[2], use Fields[3] in where clause }
      SQL := Format(UpdateStmt2, [DeltaDS.Fields[2].NewValue, DeltaDS.Fields[3].OldValue]);
      Connection.Execute(SQL, nil, nil);
    end;
  ukDelete:
    begin
     { 1st dataset: use Fields[0] in where clause }
      SQL := Format(DeleteStmt1, [DeltaDS.Fields[0].OldValue]);
      Connection.Execute(SQL, nil, nil);
     { 2nd dataset: use Fields[3] in where clause }
      SQL := Format(DeleteStmt2, [DeltaDS.Fields[3].OldValue]);
      Connection.Execute(SQL, nil, nil);
    end;
  ukInsert:
    begin
     { 1st dataset: values in Fields[0] and Fields[1] }
       SQL := Format(InsertStmt1, [DeltaDS.Fields[0].NewValue, DeltaDS.Fields[1].NewValue]);
      Connection.Execute(SQL, nil, nil);
     { 2nd dataset: values in Fields[2] and 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:
    // 1st dataset: update Fields[1], use Fields[0] in where clause
    sprintf(buffer, UpdateStmt1, DeltaDS->Fields->Fields[1]->NewValue,
            DeltaDS->Fields->Fields[0]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    // 2nd dataset: update Fields[2], use Fields[3] in where clause
    sprintf(buffer, UpdateStmt2, DeltaDS->Fields->Fields[2]->NewValue,
            DeltaDS->Fields->Fields[3]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    break;
  case ukDelete:
    // 1st dataset: use Fields[0] in where clause
    sprintf(buffer, DeleteStmt1, DeltaDS->Fields->Fields[0]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    // 2nd dataset: use Fields[3] in where clause
    sprintf(buffer, DeleteStmt2, DeltaDS->Fields->Fields[3]->OldValue);
    pConn->Execute(buffer, NULL, NULL);
    break;
  case ukInsert:
    // 1st dataset: values in Fields[0] and Fields[1]
    sprintf(buffer, UpdateStmt1, DeltaDS->Fields->Fields[0]->NewValue,
            DeltaDS->Fields->Fields[1]->NewValue);
    pConn->Execute(buffer, NULL, NULL);
    // 2nd dataset: values in Fields[2] and Fields[3]
    sprintf(buffer, UpdateStmt2, DeltaDS->Fields->Fields[2]->NewValue,
            DeltaDS->Fields->Fields[3]->NewValue);
    pConn->Execute(buffer, NULL, NULL);
    break;
}

Voir aussi