How to use UniDAC to read Record array from OLE object field of Access database?

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
Wilson Alex
Posts: 16
Joined: Fri 13 Dec 2019 16:39

How to use UniDAC to read Record array from OLE object field of Access database?

Post by Wilson Alex » Sat 09 Oct 2021 03:50

Hi,

I am using UniDAC 8.4.4 to read the data of the Access database, but one of the field types is an OLE object. What I understand is that this field is a Record array saved in a stream, which is the Record type:

TTestData = record
Time: Single; (4-byte floating point)
Load: Single; (4-byte floating point)
end;

does anyone know how to extract all Time and Load elements?

MaximG
Devart Team
Posts: 1822
Joined: Mon 06 Jul 2015 11:34

Re: How to use UniDAC to read Record array from OLE object field of Access database?

Post by MaximG » Tue 12 Oct 2021 14:58

Hi Alex!
Thank you for contacting Devart and for your inquiry!

You can save and read an array of records of type TTestData using a field of type OLE Object Microsoft Access and UniDAC. The following code sample demonstrates how to create a Microsoft Access database and store an array of two elements in an OLE Object field:

Code: Select all

   ...
var
  UniConnection: TUniConnection;
  UniQuery: TUniQuery;
  TestData: array of TTestData;
  Stream : TMemoryStream;
begin
  UniConnection := TUniConnection.Create(nil);
  try
    UniConnection.ProviderName := 'Access';
    UniConnection.Database := 'D:\Sample.accdb';
    UniConnection.SpecificOptions.Values['ForceCreateDatabase'] := 'True';
    UniConnection.SpecificOptions.Values['DriverVersion'] := 'dvAccdb';
    UniConnection.Connect;
    UniConnection.ExecSQL('CREATE TABLE MYTABLE (ID NUMBER, OLEField LONGBINARY)');
    UniQuery := TUniQuery.Create(nil);
    try
      UniQuery.Connection := UniConnection;
      UniQuery.SQL.Text := 'Select * From MYTABLE';
      UniQuery.Open;

      SetLength(TestData, 2);
      TestData[0].Time := Now;
      TestData[0].Load := EncodeDateTime(2000, 1, 23, 0, 0, 4, 123);
      TestData[1].Time := Tomorrow;
      TestData[1].Load := EncodeDateTime(2020, 12, 9, 12, 34, 54, 754);

      Stream := TMemoryStream.Create;
      try
        Stream.Size:= Length(TestData) * SizeOf(TTestData);
        Stream.Position := 0;
        Stream.Write(TestData[0], Stream.Size);
        UniQuery.Append;
        UniQuery.FieldByName('ID').AsInteger := 10;
        TBlobField(UniQuery.FieldByName('OLEField')).LoadFromStream(Stream);
        UniQuery.Post;
     finally
        Stream.Free;
      end;
    finally
      UniQuery.Free;
    end;
  finally
    UniConnection.Free;
  end;
end;
   ...
And, the following snippet demonstrates reading the previously saved value:

Code: Select all

   ...
var
  UniConnection: TUniConnection;
  UniQuery: TUniQuery;
  TestData: array of TTestData;
  Stream : TMemoryStream;
begin
  UniConnection := TUniConnection.Create(nil);
  try
    UniConnection.ProviderName := 'Access';
    UniConnection.Database := 'D:\Sample.accdb';
    UniConnection.SpecificOptions.Values['DriverVersion'] := 'dvAccdb';
    UniConnection.Connect;
    UniQuery := TUniQuery.Create(nil);
    try
      UniQuery.Connection := UniConnection;
      UniQuery.SQL.Text := 'Select * From MYTABLE';
      UniQuery.Open;

      Stream := TMemoryStream.Create;
      try
        TBlobField(UniQuery.FieldByName('OLEField')).SaveToStream(Stream);
        SetLength(TestData, Stream.Size div SizeOf(TTestData));
        Stream.Position := 0;
        Stream.Read(TestData[0], Stream.Size);
      finally
        Stream.Free;
      end;
      /// action with   TestData
      /// .......
      /// .......

    finally
      UniQuery.Free;
    end;
  finally
    UniConnection.Free;
  end;
end;
   ...

Wilson Alex
Posts: 16
Joined: Fri 13 Dec 2019 16:39

Re: How to use UniDAC to read Record array from OLE object field of Access database?

Post by Wilson Alex » Wed 13 Oct 2021 14:36

Hi MaximG, I used the sample code you gave to successfully parse out all the elements in the Record array, thank you.

Post Reply