使用poFetchBlobsOnDemand时,检查是否已获取blob字段的正确方法

时间:2011-06-08 18:54:10

标签: delphi delphi-xe tclientdataset

我有一个包含多条记录的TClientDataSet,我希望o加载所有记录,但是按需加载blob字段,一次加载一个。

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

所以我到目前为止找到的唯一解决方案是访问Value或BlobSize这样的属性,如果没有获取blob,则会发出EDBClient异常,并显示消息“Blob尚未获取”,所以如果引发此异常,调用FetchBlobs。

有没有更好的方法呢?

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

2 个答案:

答案 0 :(得分:3)

我不确定这是否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单位中似乎DSIntf定义了GetBlobLen,以便在尚未获取blob的情况下返回TCustomClientDataSet.CreateBlobStream。因此返回代码意味着'blob not fetched',成功返回代码意味着'blob fetched already',而任何其他错误代码可能表示其他一些错误。 灵感来自{{1}}。

答案 1 :(得分:1)

如果您必须知道是否已检索到blob的数据,我相信,TOndrej的answer将是您要走的路。但你没必要..

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

来自“Provider.TProviderOption Enumeration”:

  

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