Правильный способ проверить, было ли поле blob уже выбрано при использовании poFetchBlobsOnDemand - PullRequest
6 голосов
/ 08 июня 2011

У меня есть TClientDataSet с несколькими записями, и я хочу загрузить все записи, но загружать поле большого двоичного объекта по требованию, по одной за раз.

Я заметил, что при вызове FetchBlobs дважды происходит выборка двоичного объекта, а также при проверке свойства поля IsNull всегда возвращается значение False.

Таким образом, единственное решение, которое я нашел до сих пор, - это доступ к свойству, например Value или BlobSize, и, если большой двоичный объект не был получен, вызывается исключение EDBClient с сообщением "Blob не был получен", поэтому, если это исключение было поднято, я вызвать FetchBlobs.

Есть ли лучший способ сделать это?

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

Ответы [ 2 ]

3 голосов
/ 09 июня 2011

Я не уверен, что это на 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-объект не получен», успешный код возврата означает «объект BLOB-объект уже получен», а любой другой код ошибки, вероятно, указывает на некоторую другую ошибку. Вдохновлен TCustomClientDataSet.CreateBlobStream.

1 голос
/ 10 июня 2011

Если бы вам нужно было узнать, были ли получены данные BLOB-объекта, я полагаю, что ответ от TOndrej был бы подходящим вариантом.Но вам не нужно ..

Когда poFetchBlobsOnDemand установлено в параметрах «DataSetProvider», а FetchOnDemand установлено в «ClientDataSet»,поведение уже, как вы описываете.Т.е. набор данных клиента вызывает FetchBlobs только в том случае, если данные BLOB-объектов еще не были извлечены, и только тогда, когда они необходимы.

Из " Provider.TProviderOption Enumeration ":

poFetchBlobsOnDemand Поля BLOB не включены в пакеты данных.[...] Если свойство FetchOnDemand набора данных клиента имеет значение true, клиент запрашивает эти значения автоматически.[...]

...