开发者

Access the true buffer of a record in Unicode version of Delphi - ADO

开发者 https://www.devze.com 2023-04-10 00:58 出处:网络
Prior to upgrading to Delphi 2010 we were able to extract data stored in a access database string field which actually contains an array of bytes.

Prior to upgrading to Delphi 2010 we were able to extract data stored in a access database string field which actually contains an array of bytes.

This was achieved with something like:

  GetMem(buff, 66);
  try
    if Table.FieldByName('BytesInStrField').GetData(buff, True) then //True false ignored anyway
    begin
      Move(Buff^, X, 65);
    end;
  finally
    //
  end;

Since we have upgraded even the Buffer seems to stop reading at the first instance of #0#0 (String terminator)

The problem is that this data is no longer accessible to us. I would like to mention it was not myself who decided to put an array of Bytes in a Microsoft Access String Field.

Does anyone have any idea's how I can read the entire filed without truncation, I am trying hard to avoid writing my own Direct Binary Read of the entire DB.

As this is Delphi Accessing Microsoft Acc开发者_如何学编程ess I am using the TADO components.

Thanks for reading.


The GetFieldData methods of TCustomADODataSet are what you need. There are three:

function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; override;
function GetFieldData(FieldNo: Integer; Buffer: Pointer): Boolean; overload; override;

The hard work is done in the second one, which is also the one used from the TField.GetData method.

You will need to derive your own descendant of TADODataSet, override the second version of the GetFieldData method with your own version. Call inherited for all other fields, but for your specific BytesInString field, read the buffer yourself and avoid the variant conversion that is done in the TCustomADODataSet.GetFieldData method.

If you want to avoid having to insert your own descendant everywhere, declare an interceptor class in a, for example, ADOInterceptor unit:

TADODataSet = class(ADODB.TADODataSet)
public
  function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; override;
;

And make sure that this unit is used everywhere that ADODB is used and it appears AFTER the ADODB unit in the uses clause.


Did you try Table.FieldByName('BytesInStrField').AsBytes


Have you tried Table.GetBlobFieldData()?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号