2011-10-03 74 views
2

在升级到Delphi 2010之前,我们能够提取存储在实际包含字节数组的字符串的访问数据库字段中的数据。访问Unicode版本的Delphi中的记录的真正缓冲区 - ADO

这与类似实现:

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

既然我们已经升级甚至缓冲区似乎停止在#0#0(字符串结束)一审阅读

的问题是,我们无法再访问这些数据。我想提一下,不是我自己决定在Microsoft Access字符串字段中放置一个Bytes数组。

有没有人有任何想法如何我可以阅读整个领域没有截断,我努力避免编写我自己的整个数据库的直接二进制读取。

因为这是Delphi访问Microsoft Access我正在使用TADO组件。

感谢您的阅读。

+0

什么是您正在访问的字段的SQL列类型? VARCHAR? –

+0

@Warren P - 是的字段类型是VarChar这是明显的疯狂,我仍然试图解决为什么有人认为这是明智的。 – Reallyethical

回答

3

TCustomADODataSet的GetFieldData方法是您所需要的。有三个:

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; 

辛苦的工作是在第二个,也是从TField.GetData方法中使用的。

您将需要派生自己的TADODataSet的后代,用您自己的版本覆盖GetFieldData方法的第二个版本。调用继承所有其他字段,但对于特定的BytesInString字段,请自行读取缓冲区并避免在TCustomADODataSet.GetFieldData方法中完成的变体转换。

如果你想避免到处插入自己的后代,声明一个拦截器类中,例如,ADOInterceptor单位:

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

,并确保本机的使用,随处可见的是ADODB使用并且它在使用条款中的ADODB单元之后出现。

+0

我已经看过GetFieldData和DataConvert,但似乎无法步入它来检查发生了什么。我可能需要抓住缓冲区并克隆。 – Reallyethical

+0

@Reallyethical:如果你正在使用调试dcu的,我不知道是什么阻止你进入方法。但抓住缓冲区和克隆听起来好像你BytesInString字段... –

1

你尝试Table.FieldByName('BytesInStrField').AsBytes

+0

当然是的,它给出了正确的长度,但#0#0之后的数据还没有被读取,所以在#0#0的第一个实例之后所有字节都被设置为#0,当然这是错误的。 – Reallyethical

+0

@Reallyethical AsBytes返回一个'TBytes = Byte'数组类型的变量,它可能不会以第一个#0#0结束 - 或者ADO/VCL转换层存在问题。从VCL的角度来看,它将处理#0#0字节,没有任何问题。你如何使用这个AsBytes结果? –

+0

如果您仔细查看代码,您将看到DB.pas使用WideString类型的字段来填充字段,然后填充字段的字符,因此具有与丢失其余数据相同的效果。我有一种感觉,这是一个更严重的驱动程序错误,可能需要退回到此项目的D7。 – Reallyethical

1

你试过Table.GetBlobFieldData()