2011-10-03 76 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()