7

複数のレコードを持つ TClientDataSet があり、すべてのレコードをロードする必要がありますが、一度に 1 つずつオンデマンドで BLOB フィールドをロードします。

FetchBlobs を 2 回呼び出すと BLOB が 2 回フェッチされ、フィールドの IsNull プロパティをチェックすると常に False が返されることに気付きました。

したがって、これまでに見つけた唯一の解決策は、Value や BlobSize などのプロパティにアクセスすることです。BLOB がフェッチされていない場合、「Blob はフェッチされていません」というメッセージとともに例外が EDBClient に発生するため、この例外が発生した場合は FetchBlobs を呼び出します。 .

これを行うためのより良い方法はありますか?

  try
    cdsIMG.BlobSize;
  except
    on E: EDBClient do
      cds.FetchBlobs;
  end;
4

2 に答える 2

4

これが 100% 正しいかどうかはわかりませんが、私ができる最善の方法です。自分で見て。

type
  THackCustomClientDataSet = class(TCustomClientDataSet);

function IsBlobFetched(DataSet: TCustomClientDataSet; BlobField: TField): Boolean;
var
  I: Integer;
  Status: DBResult;
  BlobLen: Cardinal;
begin
  Result := False;
  BlobLen := 0;

  with THackCustomClientDataSet(DataSet) do
    if Assigned(DSCursor) and (ActiveBuffer <> nil) then
    begin
      Status := DSCursor.GetBlobLen(ActiveBuffer, BlobField.FieldNo, BlobLen);
      case Status of
        DBERR_NONE:
          Result := True;
        DBERR_BLOBNOTFETCHED:
          ;
        else
          Check(Status);
      end;
    end;
end;

ブロブがまだフェッチされていない場合に返されるユニットがDBERR_BLOBNOTFETCHED定義されているようです。そのため、リターン コードは「blob がフェッチされていない」ことを意味し、成功のリターン コードは「blob が既にフェッチされている」ことを意味し、その他のエラー コードはおそらく他のエラーを示しています。に触発されました。DSIntfGetBlobLenTCustomClientDataSet.CreateBlobStream

于 2011-06-08T20:52:42.697 に答える
2

ブロブのデータが取得されたかどうかを知る必要がある場合は、TOndrej の回答が最適です。しかし、あなたはする必要はありません..

「 DataSetProvider poFetchBlobsOnDemand」のオプションでFetchOnDemand設定され、「ClientDataSet」で設定されている場合、動作はすでに説明したとおりです。つまり、クライアント データ セットはFetchBlobs、BLOB データがまだ取得されておらず、必要な場合にのみ呼び出されます。

" Provider.TProviderOption Enumeration " から:

poFetchBlobsOnDemand     BLOB フィールドはデータ パケットに含まれません。[...] クライアント データセットの FetchOnDemand プロパティが true の場合、クライアントはこれらの値を自動的に要求します。[...]

于 2011-06-09T23:19:10.213 に答える