4

私は(Firebird)DBを持っています。ほとんどのテーブルには、挿入前に発生するトリガーがあり、ジェネレーターを介して主キー (PK) を作成し、新しく挿入されたレコードに作成日値と作成者値を書き込みます。また、更新日フィールドと更新者フィールドに書き込む更新トリガーもあります。

例(クライアントは私のDBのテーブルです):

create trigger t_client_id for client
active before insert
as begin
  new.client_id = gen_id(gen_client_id, 1);
  new.created = current_timestamp;
  new.created_by = current_user;
  new.lock_vn = 1;
end ^

create trigger t_client_update for client
active before update
as begin
  new.updated = current_timestamp;
  new.updated_by = current_user;
end ^   

TDSProviderConnection を介してリモートの TDataSetProvider に接続されている ClientDataSet (CDS) を介して更新を適用する場合、これらの生成された値を「取得」するにはどうすればよいですか? 既存のものを編集すると (t_client_update トリガーが呼び出され、RefreshRecord を呼び出すと、updated および updated_by フィールドが取得されます。ただし、Doco はそのメソッドを慎重に使用するように指示しているため、これを達成するための正しい方法ではない可能性があります。 ApplyUpdates(-1) を呼び出した直後に呼び出します。

私が使用している CDS には、編集しようとしている 1 つのレコードしか含まれていません。新規レコードの場合、CDS は dsInsert モードです。すべてが正常に DB に書き込まれるので、この新しいデータを再度取得する必要があります。また、テーブル内のすべてのレコードを含む CDS を使用して、それがより単純であるかどうかを確認しましたが、違いはありませんでした-当然のことです。この情報が必要な理由は、DB Aware コントロールでこれらの値をユーザーに表示するためです。それらは読み取り専用です。

PK を使用して既存のレコードを編集するときに推測するレコードで Get を呼び出すことができますが、新しい PK が何であるかがわからないため、Insert には役立ちません。

CDS に ApplyUpdates を試行する例 (actDSSave は TDataSetPost アクションです)

  dsState := actDSSave.DataSource.DataSet.State;
  DoApplyUpdates(-1);
  if dsState = dsEdit then
    TClientDataSet(actDSSave.DataSource.DataSet).RefreshRecord;

リモート DataSetProvider に接続されたデータセットに TIBQuery を使用しています。このクエリ SQL は単純なselect * from client where client_id = :client_idです。このクエリを TIBUpdateSQL にも関連付けようとしたほか、DataSetProvider で poAutoRefresh を true に設定しようとしました。

これらのトリガー生成値をこの方法で取得することは可能ですか、それとも別の方法でアプローチする必要がありますか? 私が考えることができる別の方法は、各テーブルに対して CRUD を実行し、代わりにそれを使用するストアド プロシージャを作成することです (適切な in/out パラメータを使用して、この新しいデータを返します)。問題を説明して再現するのに十分な情報をここで提供できれば幸いです。

ありがとう

編集 上記で実現された DoApplyUpdates(-1) は、私自身のメソッドです。現時点での実装は単純です。

FdatCommon.cdsClient.ApplyUpdates(MaxErrorCount);

FdatCommon は、私の CDS を含む TDataModule です。

4

1 に答える 1

0

Post の後にデータの新しい再クエリ (RefreshRecord) がなければ、「生成された」値を取得することはできません。

これは、ApplyUpdates を呼び出すとサーバー側でトリガーが実行されるためですが、TClientDataSet は既定では投稿されたレコードを更新しません。たとえば、他のライブラリ FIBPlus には、自動的に実行するオプションがあります。

挿入について、TIBDataSet には GeneratorField プロパティがあります。それを使用して、挿入する前に、データセットのクエリとジェネレーターの値を個別にインクリメントします。したがって、挿入後でも PK 値が得られます。ただし、トリガーで再度使用することは避けてください。

MIDAS (TClientDataSet) は優れたライブラリですが、FibPlus などの特定の DBMS 用の専用ライブラリと比較して、彼の一般的/ユニバーサル アーキテクチャは DB 固有の機能 (挿入から値を取得するなど) を緩めています。ところで、TpFIBClientDataSet を見ました。TpFibDataSet と連携して動作します。

于 2012-09-29T13:47:03.557 に答える