正確さ:私のコードは、ランタイムコマンドの結果として作成されたDelphi XE(プロパティセットでにTClientDataset
接続されている)の非物理フィールドを更新しようとしています。TSQLQuery
SQL
Open
にTClientDataset
接続されてTDatasetProvider
いるに接続TSQLQuery
されていTSQLConnection
ます。これらのオブジェクトの最初の3つは、いくつかのプロジェクトの多くの場所で使用しているライブラリのいくつかのクラスにカプセル化されています。これらのクラスは実行時にこれらの3つのオブジェクトを作成し、これらのトリプレットの多くを持っているので必要な、大量の反復コードを排除します。
非常に一般的には、のプロパティでTClientDataset
SQLを指定し、を呼び出すことによって、データベースからをロードします。のは、ieへのこの呼び出しを介して作成されます。の前には存在しません。SQL
TSQLQuery
Open
TClientDataSet
Fields
TClientDataset
Open
Open
に生成された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
フラグをクリアすることで、このエラーを回避できます。ただし、このソリューションでは、特定のフィールド名が上記の汎用クラスにあるこの関数に認識されている必要があるため、コードの一般性が損なわれます。TDatasetProvider
OnUpdateData
私が探しているのは、これらのフィールドの計算された性質をイベントハンドラー関数に通知する一般的な手段です。
呼び出し後にFieldKind
orCalculated
プロパティを(fkInternalCalc
それぞれTrue
に)変更することはできません。これにより、例外メッセージが生成されるためです。また、まだ存在しないため、呼び出し前にこれらのプロパティを変更することはできません。Open
WorkCDS: Cannot perform this operation on an open dataset
Open
Fields
後でこれらのプロパティpfInUpdate
からフラグを削除できますが、これはイベントハンドラーに到着する「デルタ」に渡されません。また、フィールドのプロパティを設定してみました。繰り返しますが、これはDeltaデータセットに渡されません。Field
ProviderFlags
Open
TClientDatset
OnUpdateData
FieldDefs.InternalCalcField
ですから、私が試したすべてのシグナリングのアイデアはうまくいきませんでした。新しいアイデアや別のアプローチに感謝します。
私が遭遇したすべてのインターネット検索結果(Cary Jensenの優れた記事を含む)は、私の状況に当てはまらない設計時またはSQL以外で生成されたセットアップを扱っています。