Correct way to check if a blob field has already been fetched when using poFetchBlobsOnDemand
Asked Answered
H

2

7

I have a TClientDataSet with several records, and I want o load all the records, but load the blob field on Demand, one at a time.

I noticed that calling FetchBlobs twice fetches the blob twice and also that checking the field's IsNull property always returns False.

So the only solution I found so far is to access a property like Value or BlobSize and if the blob has not been fetched an exception is raised EDBClient with message "Blob has not been fetched", so if this exception is raised I call the FetchBlobs.

Is there some better way of doing this?

  try
    cdsIMG.BlobSize;
  except
    on E: EDBClient do
      cds.FetchBlobs;
  end;
Hierarchy answered 8/6, 2011 at 18:54 Comment(5)
When poFetchBlobsOnDemand is set together with FetchOnDemand of the dataset, the behavior is already as you describe. I.e. the client data set calls FetchBlobs only if it the blob data has not already been retrieved and only when it is needed (See code in 'TCustomClientDataSet.CreateBlobStream' in DBClient.pas). I don't understand why you have to duplicate the exact behavior manually..Gally
Why don't you answer this in the question so I can select it as the correct answer? :PHierarchy
@Fabio - Have I misunderstood your comment? I'd like to delete my answer if I did..Gally
@Sertac What I meant was that instead of commenting, you should create a new answer in the question, so I could mark it as the correct anwser, because it solved my problem.Hierarchy
@Fabio - Undeleted the answer.. Is this OK? :)Gally
G
2

If you had to know if a blob's data had been retrieved, I believe, TOndrej's answer would be the way to go. But you don't have to..

When poFetchBlobsOnDemand is set in 'DataSetProvider's options, and FetchOnDemand is set on the 'ClientDataSet', the behavior is already as you describe. I.e. the client data set calls FetchBlobs only if the blob data has not already been retrieved and only when it is needed.

From "Provider.TProviderOption Enumeration":

poFetchBlobsOnDemand    BLOB fields are not included in data packets. [...] If the client dataset's FetchOnDemand property is true, the client requests these values automatically. [...]

Gally answered 9/6, 2011 at 23:19 Comment(0)
J
4

I'm not sure if this is 100% correct but it's the best I could do. See for yourself.

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;

There seems to be DBERR_BLOBNOTFETCHED defined in DSIntf unit to be returned by GetBlobLen in case the blob has not been fetched yet. So that return code means 'blob not fetched', success return code means 'blob fetched already', and any other error code probably indicates some other error. Inspired by TCustomClientDataSet.CreateBlobStream.

Jammiejammin answered 8/6, 2011 at 20:52 Comment(0)
G
2

If you had to know if a blob's data had been retrieved, I believe, TOndrej's answer would be the way to go. But you don't have to..

When poFetchBlobsOnDemand is set in 'DataSetProvider's options, and FetchOnDemand is set on the 'ClientDataSet', the behavior is already as you describe. I.e. the client data set calls FetchBlobs only if the blob data has not already been retrieved and only when it is needed.

From "Provider.TProviderOption Enumeration":

poFetchBlobsOnDemand    BLOB fields are not included in data packets. [...] If the client dataset's FetchOnDemand property is true, the client requests these values automatically. [...]

Gally answered 9/6, 2011 at 23:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.