我有一个包含多条记录的TClientDataSet,我希望o加载所有记录,但是按需加载blob字段,一次加载一个。
我注意到调用FetchBlobs两次获取blob两次,并且检查字段的IsNull属性总是返回False。
所以我到目前为止找到的唯一解决方案是访问Value或BlobSize这样的属性,如果没有获取blob,则会发出EDBClient异常,并显示消息“Blob尚未获取”,所以如果引发此异常,调用FetchBlobs。
有没有更好的方法呢?
try
cdsIMG.BlobSize;
except
on E: EDBClient do
cds.FetchBlobs;
end;
答案 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,客户端请求 这些值自动生成。 [...]