1

TDataSetProvider.OnUpdateData イベントの説明に関する Delphi ヘルプ ファイルを読んだ後:

  1. データを調べて (たとえば、許可されるべきではない値やデータの変更について)、更新が発生する前に適用をキャンセルする例外を発生させます。
  2. ソース データセットまたはデータベース サーバーに送信される前に、データを変更します (たとえば、値の暗号化または復号化)。

OnUpdateData のデータを変更する方法のサンプル コードを探しています。私は解決策を探すために最善を尽くしました。これは私が達成できるものです:

例 1 :

procedure TDBNextDocNo.DSPUpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.EOF do begin
    if DataSet.UpdateStatus = usUnmodified then begin
      TPacketDataSet(Dataset).InitAltRecBuffers(True);
      if DataSet.UpdateStatus in [usInserted, usModified] then begin
        Dataset.Edit;
        DataSet.FindField('MyField').AsString := 'zzz';
        Dataset.Post;
      end;
    end;
  end;
  DataSet.Next;
end;

例 1 の問題: 残念ながら、一部のフィールド値が欠落しているというエラーが表示され続けます。いくつかのデバッグを実行した後、値が空の必須フィールドがあることがわかりました。

例 2:

procedure TDBNextDocNo.DSPUpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.EOF do begin
    if DataSet.UpdateStatus = usUnmodified then begin
      TPacketDataSet(Dataset).InitAltRecBuffers(True);
      if DataSet.UpdateStatus in [usInserted, usModified] then 
        DataSet.FindField('MyField').NewValue:= 'zzz';     
    end;
    DataSet.Next;
  end;  
end;

例 2 の問題: このように記述すると、DataSet.Edit と DataSet.Post を呼び出す必要がなくなります。しかし、TField.NewValue に設定された値「zzz」はデータベースに保存されていません。

この更新は、BeforeUpdateRecord/AfterUpdateRecord ではなく OnUpdateData で実行する必要がある特別な理由があります。

ご意見をお聞かせください。どうもありがとうございました。

4

2 に答える 2

0

さて、最初から始めましょう。

デルタでは、変更が記録されます(私の経験では):

  • 削除されたレコードと挿入されたレコードのストレージは、UpdateStatus でのみ異なります
    • それぞれのステータスを持つ 1 つのレコード
  • 編集されたレコードは別の方法で保存されます - 2 つのレコードがそのように保存されます (そしてIN THAT ORDER )
    • UpdateStatus = usUnModified の 1 レコード
    • UpdateStatus = usModified の 1 レコード - このレコードには、変更されたフィールドの値のみが含まれます。他のフィールドはすべて空です。

デルタ変更の進め方

挿入/削除されたレコードの場合

StatusFilter を [usInserted] および/または [usDeleted] に設定します。それらを変更します。あなたは終わった。

変更されたレコードの場合

SetStatusFiler を [usUnModified,usModified] に設定して、Delta の両方のレコードを表示します。各 UpdateStatus = usUnModifiedWhile not DSDelta.Eof doに対してテストを実行します。はいの場合は、次のレコードの変更に進みます (テストしたレコードに対応する UpdateStatus = usModified)。それ以外の場合は、UpdateStatus = usUnModified の次のレコードを探します。

編集:そうです。必須とマークされているすべてのフィールドを含めない場合、変更されたレコードのデルタのフィールドを変更する方法はありません。

コードは次の場所に移動します。

procedure TDBNextDocNo.DSPUpdateData(Sender: TObject; DataSet: TCustomClientDataSet);
begin
  DataSet.First;
  while not DataSet.EOF do begin
    if DataSet.UpdateStatus = usUnmodified then begin
      TPacketDataSet(Dataset).InitAltRecBuffers(True);
      if DataSet.UpdateStatus in [usInserted, usModified] then begin
        Dataset.Edit;
        DataSet.FindField('MyField').AsString := 'zzz';

        If Dataset.UpdateStatus in [usModified] then
        begin
          for i = 0 to Dataset.FieldCount - 1 do
          begin
            If Dataset.Fields[i].Name <> 'MyField' then
            begin
              If Dataset.Fields[i].Required then
                Dataset.Fields[i].Value := Dataset.Fields[i].OldValue; 
            end; 
          end;
        end;
        Dataset.Post;
      end;
    end;
  end;
  DataSet.Next;
end;
于 2011-06-30T18:25:34.963 に答える
0

そうじゃない

DataSet.UpdateStatus = usUnmodified の場合、開始

[usInserted, usModified] の DataSet.UpdateStatus の場合

相互排他的?最後が間違っているか、else がない可能性があります。

于 2011-06-30T17:05:55.190 に答える