2009-07-08 18 views
5

Nel gestore eventi AfterPost per ClientDataSet, ho bisogno delle informazioni se la funzione ApplyUpdates per il record corrente farà un aggiornamento o un inserimento.Come posso rilevare se ApplyUpdates inserirà o aggiornerà i dati?

L'evento AfterPost verrà eseguito per i record nuovi e aggiornati e non desidero dichiarare una nuova variabile Flag per indicare se è in corso un'operazione di 'aggiornamento' o 'inserimento'.

codice Esempio:

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

    QryTest.ApplyUpdates(-1); 
end; 

L'applicazione scriverà un registro nel metodo Afterpost, dopo ApplyUpdate ha completato. Quindi questo metodo è il posto più vicino all'azione, preferirei una soluzione che possa essere completamente inserita in questo gestore di eventi.

Come è possibile implementare la funzione IsInserting, utilizzando le informazioni nell'istanza di ClientDataSet QryTest?

Modifica: Proverò ClientDataSet.UpdateStatus che è spiegato here.

+0

Che cosa hai intenzione di fare? Effettua convalide, aggiorna l'interfaccia utente o manipola alcuni dati? – zendar

+0

L'applicazione scriverà un registro nel metodo AfterPost, dopo che ApplyUpdate è stato completato. Quindi questo metodo è il posto più vicino all'azione, preferirei una soluzione che possa essere completamente inserita in questo gestore di eventi. Controllare l'array Delta qui sembra essere il modo più semplice. – mjn

+0

Questo è il posto migliore se si registra per utente, sul lato client. Se si desidera il registro centrale per tutti gli utenti, il posto migliore sarebbe sul lato server nell'evento AfterApplyUpdates su TDataSetProvider. – zendar

risposta

5

ApplyUpdates non fornisce tali informazioni, poiché può essere Inserimento, aggiornamento e cancellazione.

ApplyUpdates applica le informazioni sulle modifiche memorizzate sull'array Delta. Le informazioni sulle modifiche possono, ad esempio, contenere un numero qualsiasi di modifiche di tipi diversi (inserzioni, eliminazioni e aggiornamenti) e tutte queste verranno applicate alla stessa chiamata.

Su TDatasetProvider si ha l'evento BeforeUpdateRecord (o qualcosa del genere, il sonno fa cose divertenti in memoria :-)). Questo evento viene chiamato prima che ogni record di Delta venga applicato al database/set di dati sottostante e quindi al luogo in cui ottenere tali informazioni ... Ma Showmessage interromperà il processo di applicazione.

EDIT: Ora mi sono ricordato che c'è un'altra opzione: è possibile assegnare a Delta un'altra proprietà Datadataset client e leggere il set di dati UpdateStatus per quel record. Naturalmente, è necessario fare questo prima facendo ApplyUpdates ...

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

Questo suona molto bene. Se l'UpdateUpdate è legato solo a un record, l'arry delta conterrà solo una voce che sa se si tratta di un aggiornamento o di un inserimento? Quindi ho bisogno solo di un modo per accedere a queste informazioni nel Delta. – mjn

+0

Perché usa un secondo CDS? Mi aspetto che UpdateStatus sia già disponibile nel primo CDS, quindi potrei semplicemente leggerlo direttamente. O è StatusFilter la risposta perché è necessario un secondo? – mjn

+0

Perché con il 2 ° CD avrai solo il contenuto del Delta e niente di più. Ma è solo un modo alternativo di fare la cosa, senza passare attraverso il provider di dati. –

4

evento BeforeUpdateRecord su TDataSetProvider è definito come:

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

Parametro UpdateKind dice che cosa sarà fatto con il record: ukModify, ukInsert or ukDelete . È possibile verificare in questo modo:

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; 

Nota: questo evento è la firma da Delphi 7. Non so se è cambiato nelle versioni successive di Delphi.

2

Impostare la ClientDataSet.StatusFilter ad un valore TUpdateStatus, e quindi leggere ClientDataSet.RecordCount

per esempio,

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

restituirà il numero di query di eliminazione che verranno eseguiti.

Nota due cose, tuttavia.Impostare StatusFilter su usModified include sempre sia i record modificati che quelli non modificati, quindi prendi la metà di quel valore (un valore di 4 significa che verranno eseguite 2 query di aggiornamento). Inoltre, impostare StatusFilter su [] (un set vuoto) è come ripristinare la visualizzazione predefinita (Modificato, Non modificato e Inserito)

Assicurarsi che tutte le modifiche non pubblicate siano state pubblicate prima di fare questo, altrimenti le modifiche non pubblicate potrebbero non essere considerato.

+0

Mille grazie, questo era il pezzo mancante della soluzione più semplice! Vedi il mio commento nella risposta di Fabricio Araujo. – mjn

Problemi correlati