2009-07-08 6 views
5

ClientDataSetのAfterPostイベントハンドラで、現在のレコードのApplyUpdates関数が更新または挿入を行う場合、情報が必要です。ApplyUpdatesがデータを挿入または更新するかどうかを検出するにはどうすればよいですか?

AfterPostイベントは新しいレコードと更新されたレコードに対して実行され、新しいフラグ変数を宣言して「更新」または「挿入」操作が進行中かどうかを示しません。

例コード:ApplyUpdateが完了した後

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

    QryTest.ApplyUpdates(-1); 
end; 

アプリケーションは、AfterPost方法でログを書き込みます。このメソッドはアクションに最も近い場所ですので、このイベントハンドラに完全に挿入できるソリューションを好むでしょう。

ClientDataSetインスタンスQryTestの情報を使用して、IsInserting関数を実装するにはどうすればよいですか?

を編集してください:hereで説明されているClientDataSet.UpdateStatusを試してみます。

+0

あなたは何をする予定ですか?検証、ユーザーインターフェイスの更新、または一部のデータ操作の更新? – zendar

+0

アプリケーションは、ApplyUpdateが完了した後、AfterPostメソッドにログを書き込みます。このメソッドはアクションに最も近い場所ですので、このイベントハンドラに完全に挿入できるソリューションを好むでしょう。ここでデルタ配列を確認するのが最も簡単な方法です。 – mjn

+0

これは、クライアント側でユーザーごとにログを記録する場合に最適です。すべてのユーザーの集中ログを作成する場合は、TDataSetProviderのAfterApplyUpdatesイベントでサーバー側に配置する方がよいでしょう。 – zendar

答えて

5

ApplyUpdatesでは、情報の挿入、更新、削除を行うことができます。

ApplyUpdatesは、デルタ配列に格納された変更情報を適用します。その変更情報には、たとえば、さまざまなタイプの変更(挿入、削除および更新)が含まれていてもよく、これらのすべてが同じ呼び出しで適用されます。

TDatasetProviderでは、BeforeUpdateRecordイベント(またはそのようなものです。sleepはメモリ上で面白いことをします:-))。このイベントは、デルタの各レコードが基になるデータベース/データセットに適用される前に呼び出され、その情報を取得する場所です...しかし、Showmessageは適用プロセスを停止します。

EDIT:別のオプションがあります。デルタを別のclientdatasetデータプロパティに割り当て、そのレコードのデータセットUpdateStatusを読み込むことができます。 もちろん、あなたがApplyUpdatesメソッドをやって前にこのを行う必要があります... TDataSetProviderに

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

これはとても良いですね。 ApplyUpdateが1つのレコードにのみ関連する場合、Delta arryには更新または挿入の有無を知るエントリが1つだけ含まれます。だから私はデルタでこの情報にアクセスするための方法が必要です。 – mjn

+0

なぜ2番目のCDSを使用していますか?私はUpdateStatusがすでに最初のCDSで利用可能であると期待しているので、ただそれを直接読むことができます。または、StatusFilterはなぜ2番目のものが必要なのかの答えですか? – mjn

+0

2番目のCDでは、デルタだけの内容しか持たないでしょう。しかし、これは、データセットプロバイダを経由せずに、これを行う別の方法です。 –

4

BeforeUpdateRecordイベントは次のように定義されます

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

パラメータUpdateKindは、レコードで行われるものを言う:ukModify, ukInsert or ukDelete 。あなたはこのようにそれをテストすることができます。

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; 

注:このイベント署名は、デルファイのそれ以降のバージョンで変更された場合、私は知らないのDelphi 7からです。例えばClientDataSet.RecordCount

を読み取り、次いでTUpdateStatus値にClientDataSet.StatusFilterを設定し、

2

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

が実行される削除クエリの数を返します。

ただし、2つのことに注意してください。StatusFilterをusModifiedに設定すると、変更されたレコードと変更されていないレコードの両方が常に含まれるため、その値の半分をとります(値4は2つのUpdateクエリが実行されることを意味します)。また、StatusFilterを[](空のセット)に設定すると、デフォルトのビュー(変更済み、未変更、挿入済み)に復元する方法

これを行う前に投稿されていない変更が投稿されていることを確認してください。考慮される。

+0

多くのおかげで、これは最も簡単な解決策の欠けていた部分でした! Fabricio Araujoの答えに私のコメントを見てください。 – mjn

関連する問題