7

我有一个带有多条记录的 TClientDataSet,我想加载所有记录,但一次加载一个按需加载 blob 字段。

我注意到调用 FetchBlobs 两次获取 blob 两次,并且检查字段的 IsNull 属性总是返回 False。

因此,到目前为止,我发现的唯一解决方案是访问 Value 或 BlobSize 之类的属性,如果尚未获取 Blob,则会引发 EDBClient 异常,并显示消息“尚未获取 Blob”,因此如果引发此异常,我将调用 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;

如果尚未获取 blob,则似乎在要返回的单元中DBERR_BLOBNOTFETCHED定义。因此,返回代码表示“未获取 blob”,成功返回代码表示“已获取 blob”,任何其他错误代码都可能表示其他错误。灵感来自.DSIntfGetBlobLenTCustomClientDataSet.CreateBlobStream

于 2011-06-08T20:52:42.697 回答
2

如果您必须知道是否已检索到 blob 的数据,我相信,TOndrej 的答案将是可行的方法。但你不必..

poFetchBlobsOnDemand在“DataSetProvider”选项FetchOnDemand中设置,并在“ClientDataSet”上设置时,行为已经如您描述的那样。即客户端数据集FetchBlobs仅在尚未检索到 blob 数据且仅在需要时才调用。

来自“ Provider.TProviderOption 枚举”:

poFetchBlobsOnDemand     BLOB 字段不包含在数据包中。[...] 如果客户端数据集的 FetchOnDemand 属性为真,客户端会自动请求这些值。[...]

于 2011-06-09T23:19:10.213 回答