正確さ:私のコードは、ランタイムコマンドの結果として作成されたDelphi XE(プロパティセットでにTClientDataset接続されている)の非物理フィールドを更新しようとしています。TSQLQuerySQLOpen
にTClientDataset接続されてTDatasetProviderいるに接続TSQLQueryされていTSQLConnectionます。これらのオブジェクトの最初の3つは、いくつかのプロジェクトの多くの場所で使用しているライブラリのいくつかのクラスにカプセル化されています。これらのクラスは実行時にこれらの3つのオブジェクトを作成し、これらのトリプレットの多くを持っているので必要な、大量の反復コードを排除します。
非常に一般的には、のプロパティでTClientDatasetSQLを指定し、を呼び出すことによって、データベースからをロードします。のは、ieへのこの呼び出しを介して作成されます。の前には存在しません。SQLTSQLQueryOpenTClientDataSetFieldsTClientDatasetOpenOpen
に生成された3つのフィールドTClientDatasetが非物理的である状況で問題が発生しました。つまり、SQLはそれらを生成するために計算を行います。残念ながら、ではTClientDataset、これらの3つのフィールドは物理フィールドと同じように作成されます。それらFieldKindはfkData(理想的にはfkInternalCalc)、CalculatedプロパティはFalse(理想的にはTrue)、そしてそれらのProviderFlagsインクルードpfInUpdate(理想的にはそうではない)です。当然のことながら、例外を実行するときが来るとApplyUpdates、TClientDataset例外がスローされます...
Project XXX.exe raised exception class TDBXError with message
SQL State: 42S22, SQL Error Code: 207 Invalid column name 'Received'.
SQL State: 42S22, SQL Error Code: 207 Invalid column name 'Issued'.
SQL State: 42S22, SQL Error Code: 207 Invalid column name 'DisplayTime'.
のイベントハンドラでこれらのフィールドのpfInUpdateフラグをクリアすることで、このエラーを回避できます。ただし、このソリューションでは、特定のフィールド名が上記の汎用クラスにあるこの関数に認識されている必要があるため、コードの一般性が損なわれます。TDatasetProviderOnUpdateData
私が探しているのは、これらのフィールドの計算された性質をイベントハンドラー関数に通知する一般的な手段です。
呼び出し後にFieldKindorCalculatedプロパティを(fkInternalCalcそれぞれTrueに)変更することはできません。これにより、例外メッセージが生成されるためです。また、まだ存在しないため、呼び出し前にこれらのプロパティを変更することはできません。OpenWorkCDS: Cannot perform this operation on an open datasetOpenFields
後でこれらのプロパティpfInUpdateからフラグを削除できますが、これはイベントハンドラーに到着する「デルタ」に渡されません。また、フィールドのプロパティを設定してみました。繰り返しますが、これはDeltaデータセットに渡されません。FieldProviderFlagsOpenTClientDatsetOnUpdateDataFieldDefs.InternalCalcField
ですから、私が試したすべてのシグナリングのアイデアはうまくいきませんでした。新しいアイデアや別のアプローチに感謝します。
私が遭遇したすべてのインターネット検索結果(Cary Jensenの優れた記事を含む)は、私の状況に当てはまらない設計時またはSQL以外で生成されたセットアップを扱っています。