更新適用時の介入

提供: RAD Studio
移動先: 案内検索

レコードの更新 への移動


クライアント データセットで更新が適用される際は、データベース サーバーまたはソース データセットへの挿入データ、削除データ、変更データの書き込みを処理する方法をプロバイダ側で決定します。TClientDataSet を外部プロバイダ コンポーネントで使用する場合は、そのプロバイダのプロパティとイベントを使用して、更新の適用方法を制御することができます。これらについては、「クライアントの更新リクエストへの応答」を参照してください。

ただし、クライアント データセットがデータ アクセス メカニズムに関連付けられている場合のように、プロバイダが内部にある場合は、プロバイダのプロパティを設定したり、イベント ハンドラを用意することはできません。そのため、クライアント データセットでは、内部プロバイダによる更新の適用方法を制御できる 1 つのプロパティと 2 つのイベントを公開しています。

  • UpdateMode では、更新の適用のためにプロバイダで生成される SQL 文でレコードの特定に使用されるフィールドを制御します。UpdateMode はプロバイダの UpdateMode プロパティと同一です。プロバイダの UpdateMode プロパティについての詳細は、「更新の適用方法への影響」を参照してください。
  • OnGetTableName を使用すると、更新の適用先となるデータベース テーブルの名前をプロバイダに指定できます。これによりプロバイダは、CommandText で指定されたストアド プロシージャやクエリからデータベース テーブルを特定できない場合、更新用の SQL 文を生成できます。たとえば、単一テーブルの更新のみ必要な複数テーブル結合をクエリで実行する場合は、OnGetTableName イベントのハンドラを提供すると、内部プロバイダは更新を正しく適用できるようになります。OnGetTableName イベントのハンドラには、パラメータが 3 つあります。つまり、内部プロバイダ コンポーネント、データをサーバーから取得した内部データセット、生成された SQL で使用するテーブル名を返すパラメータです。
  • BeforeUpdateRecord はデルタ パケット内のレコードごとに発生します。このイベントによって、レコードの挿入、削除、変更の直前に変更を行えるようになります。また、プロバイダで正しい SQL を生成できない場合(たとえば、複数のテーブルを更新する必要がある複数テーブル結合の場合など)には、更新を適用する独自の SQL 文を実行する手段にもなります。BeforeUpdateRecord イベントのハンドラには、パラメータが 5 つあります。つまり、内部プロバイダ コンポーネント、データをサーバーから取得した内部データセット、更新されようとしているレコード上に位置するデルタ パケット、更新が挿入、削除、変更のどれであるかを示す情報、イベント ハンドラで更新が実行されたかどうかを返すパラメータです。これらの使い方を以下のイベント ハンドラの例で示します。簡単にするため、この例では、SQL 文がフィールド値のみ必要なグローバル変数として使用できると仮定しています。
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;
}

関連項目