2009-07-08 4 views
5

Dans le gestionnaire d'événements AfterPost pour un ClientDataSet, j'ai besoin des informations si la fonction ApplyUpdates de l'enregistrement en cours effectue une mise à jour ou une insertion. L'événement AfterPost sera exécuté pour les enregistrements nouveaux et mis à jour, et je ne souhaite pas déclarer une nouvelle variable Flag pour indiquer si une opération 'update' ou 'insert' est en cours.Comment puis-je détecter si ApplyUpdates va insérer ou mettre à jour des données?

code Exemple:

procedure TdmMain.QryTestAfterPost(DataSet: TDataSet); 
begin 
    if IsInserting(QryTest) then 
    // ShowMessage('Inserting')... 
    else 
    // ShowMessage('Updating'); 

    QryTest.ApplyUpdates(-1); 
end; 

L'application écrire un journal dans la méthode AfterPost, après ApplyUpdate terminée. Donc cette méthode est l'endroit le plus proche de l'action, je préférerais une solution qui puisse être complètement insérée dans ce gestionnaire d'évènement.

Comment pourrais-je implémenter la fonction IsInserting, en utilisant des informations dans l'instance ClientDataSet QryTest?

Modifier: Je vais essayer ClientDataSet.UpdateStatus qui est expliqué here.

+0

Que comptez-vous faire? Faire des validations, mettre à jour l'interface utilisateur ou manipuler des données? – zendar

+0

L'application écrit un journal dans la méthode AfterPost, une fois que ApplyUpdate est terminée. Donc cette méthode est l'endroit le plus proche de l'action, je préférerais une solution qui puisse être complètement insérée dans ce gestionnaire d'évènement. Vérification du tableau Delta ici semble être le moyen le plus facile. – mjn

+0

C'est le meilleur endroit si vous vous connectez par utilisateur, côté client. Si vous voulez un journal central pour tous les utilisateurs, un meilleur endroit serait du côté serveur dans l'événement AfterApplyUpdates sur TDataSetProvider. – zendar

Répondre

5

AppliquerUpdates ne vous donne pas cette information - car il peut être l'insertion, la mise à jour et la suppression. ApplyUpdates applique les informations de modification stockées sur le tableau Delta. Ces informations de changement peuvent, par exemple, contenir un nombre quelconque de changements de types différents (insertions, suppressions et mises à jour) et tous ces changements seront appliqués au même appel.

Sur TDatasetProvider vous avez l'événement BeforeUpdateRecord (ou quelque chose comme ça, le sommeil fait des choses amusantes dans la mémoire :-)). Cet événement est appelé avant que chaque enregistrement de Delta ne soit appliqué à la base de données ou à l'ensemble de données sous-jacent et donc à l'endroit où obtenir ces informations ... Mais Showmessage arrêtera le processus d'application.

EDIT: Maintenant, je me suis souvenu qu'il y a une autre option: vous pouvez assigner Delta à une autre propriété Data clientdataset Data et lire l'ensemble de données UpdateStatus pour cet enregistrement. Bien sûr, vous devez le faire avant ApplyUpdates faisant ...

var 
    cdsAux: TClientDataset; 
begin 
    . 
    . 
    <creation of cdsAux> 
    cdsAUx.Data := cdsUpdated.Delta; 
    cdsAux.First; 
    case cdsAux.UpdateStatus of 
    usModified: 
     ShowMessage('Modified'); 
    usInserted: 
     ShowMessage('Inserted'); 
    usDeleted: 
     ShowMessage('Deleted'); // For this to work you have to modify 
           // TClientDataset.StatusFilter 
    end; 
    <cleanup code> 
end; 
+0

Cela semble très bien. Si le ApplyUpdate est seulement lié à un enregistrement, le Delta arry contiendra seulement une entrée qui sait s'il s'agit d'une mise à jour ou d'un insert? J'ai donc seulement besoin d'un moyen d'accéder à cette information dans le Delta. – mjn

+0

Pourquoi utilise-t-il un second CDS? Je m'attendrais à ce que UpdateStatus soit déjà disponible dans le premier CDS, donc je pourrais le lire directement. Ou est StatusFilter la réponse pourquoi un deuxième est nécessaire? – mjn

+0

Parce qu'avec le 2ème cds vous aurez juste le contenu du Delta, et rien de plus. Mais c'est juste une manière alternative de faire la chose, sans passer par le fournisseur de jeu de données. –

4

événement BeforeUpdateRecord sur TDataSetProvider est défini comme:

procedure BeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet; DeltaDS: 
          TCustomClientDataSet; UpdateKind: TUpdateKind; 
          var Applied: Boolean); 

Paramètre UpdateKind dit ce qui sera fait avec enregistrement: ukModify, ukInsert or ukDelete . Vous pouvez le tester comme ceci:

procedure TSomeRDM.SomeProviderBeforeUpdateRecord(Sender: TObject; 
     SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; 
     var Applied: Boolean); 
begin 
    case UpdateKind of 
    ukInsert : 
     // Process Insert; 
    ukModify : 
     // Process update 
    ukDelete : 
     // Process Delete 
    end; 
end; 

Note: cette signature de l'événement est de Delphi 7. Je ne sais pas si cela a changé dans les versions ultérieures de Delphi.

2

Réglez le ClientDataSet.StatusFilter à une valeur TUpdateStatus, puis lisez ClientDataSet.RecordCount

par exemple,

ClientDataSet1.StatusFilter := [usDeleted]; 
ShowMessage(IntToStr(ClientDataSet1.RecordCount)); 

renverra le nombre de requêtes de suppression qui seront exécutées.

Notez deux choses cependant.La définition de StatusFilter sur usModified inclut toujours les enregistrements modifiés et non modifiés, donc vous prenez la moitié de cette valeur (une valeur de 4 signifie que 2 requêtes de mise à jour seront exécutées). De plus, en définissant StatusFilter sur [] (un ensemble vide), vous rétablissez l'affichage par défaut (Modifié, Non modifié et Inséré)

Assurez-vous que toutes les modifications non intégrées ont été validées avant de procéder, sinon les modifications non intégrées risquent de ne pas être appliquées. pris en considération.

+0

Merci beaucoup, c'était la pièce manquante de la solution la plus simple! Voir mon commentaire dans la réponse de Fabricio Araujo. – mjn

Questions connexes