2010-12-20 214 views
0

我有一個非常好的DirectMySQL單元,它已準備就緒,我希望它是一個TDataset後代,因此我可以將它與QuickReport一起使用,我只是希望與來自TDataset的後代的DirectMySQL進行MySQL查詢。TDataSet Descendant

一切都很好,直到我試圖訪問一個有10.000行和更多的大表。這是不穩定的,錯誤是不可預知的,並不總是顯示,但它可能發生在你與其他表玩。它發生在GetFieldData(Field:TField; Buffer:Pointer):boolean;用於從MySQL行獲取字段值。

下面的代碼,

function TMySQLQuery.GetFieldData(Field: TField; Buffer: Pointer): Boolean; 
var 
    I, CT: Integer; 
    Row: TMySQL_Row; 
    TBuf: PChar; 
    FD: PMySQL_FieldDef; 
begin 
    UpdateCursorPos; ------------> This code is after i got the error but no result 
    Resync([]);  ------------> This code is after i got the error but no result 
    Result := false; 

    Row := oRecordset.CurrentRow; 
    I := Field.FieldNo-1; 
    FD := oRecordset.FieldDef(I); 
    if Not Assigned(FD) then 
    FD := oRecordset.FieldDef(I); 
    TBuf := PP(Row)[i]; 

    Try 
    CT := MySQLWriteFieldData(fd.field_type, fd.length, fd.decimals, TBuf, PChar(Buffer)); 
    Result := Buffer <> nil; 

    Finally 
    Row := nil; ------------> This code is after i got the error but no result 
    FD := nil; ------------> This code is after i got the error but no result 
    TBuf := nil; ------------> This code is after i got the error but no result 
    Buffer := nil; ------------> This code is after i got the error but no result 
    End; 
end; 

{ 
These codes below are to translate the data type 
from MySQL Data type to a TDataset data type 
and move mysql row (TBuf) to TDataset buffer to display. 
And error always comes up from this function 
when moving mysql row to buffer. 
} 
function TMySQLQuery.MySQLWriteFieldData(AType: byte; 
    ASize: Integer; ADec: cardinal; Source, Dest: PChar): Integer; 
var 
    VI: Integer; 
    VF: Double; 
    VD: TDateTime; 
begin 
    Result := MySQLDataSize(AType, ASize, ADec); 

    case AType of 
     FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG, 
     FIELD_TYPE_INT24: 
     begin 
       if Source <> '' then 
       VI := StrToInt(Source) 
       else 
        VI := 0; 
       Move(VI, Dest^, Result); 
     end; 
     FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL: 
     begin 
       if source <> '' then 
       VF := internalStrToCurr(Source) 
       else 
       VF := 0; 
       Move(VF, Dest^, Result); 
     end; 
     FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: 
     begin 
       if Source <> '' then 
       VF := InternalStrToFloat(Source) 
       else 
        VF := 0; 
       Move(VF, Dest^, Result); 
     end; 
     FIELD_TYPE_TIMESTAMP: 
     begin 
       if Source <> '' then 
       VD := InternalStrToTimeStamp(Source) 
       else 
        VD := 0; 
       Move(VD, Dest^, Result); 
     end; 
     FIELD_TYPE_DATETIME: 
     begin 
       if Source <> '' then 
       VD := InternalStrToDateTime(Source) 
       else 
        VD := 0; 
       Move(VD, Dest^, Result); 
     end; 
     FIELD_TYPE_DATE: 
     begin 
       if Source <> '' then 
       VD := InternalStrToDate(Source) 
       else 
        VD := 0; 
       Move(VD, Dest^, Result); 
     end; 
     FIELD_TYPE_TIME: 
     begin 
       if Source <> '' then 
       VD := InternalStrToTime(Source) 
       else 
        VD := 0; 
       Move(VD, Dest^, Result); 
     end; 
     FIELD_TYPE_STRING, FIELD_TYPE_VAR_STRING, 
     FIELD_TYPE_ENUM, FIELD_TYPE_SET: 
     begin 
       if Source = nil then 
       Dest^ := #0 
       else 
       Move(Source^, Dest^, Result); 
     end; 

     Else 
      Result := 0; 
      Raise EMySQLError.Create('Write field data - Unknown type field'); 
    end; 
end; 

我現在的猜測是它的內存相關的問題。

我堆放。任何人可以幫忙? 我還需要TDataset文檔列出可用後代函數以及如何使用它,或者如何從TDataset派生後代。任何人有他們?我缺乏這種心態。

+0

methinks - TL; DR。 Delphi還提供TDataSet文檔和源代碼。無論如何,MySQL並不能真正處理大型行集。 – 2010-12-20 03:30:03

回答

2
  1. GetFieldData不能有UpdateCursorPos和Resync調用。否則,您可能會收到不可預知的錯誤。
  2. FD:= oRecordset.FieldDef(I)... FD:= oRecordset.FieldDef(I); - 看起來很奇怪。第二個分配是不需要的。
  3. finally ...以局部變量結束不需要重置。
  4. 我不知道什麼返回MySQLDataSize。例如,MySQLDataSize可能會以Delphi數據類型表示單位返回大小,或者可能返回MySQL返回的數據長度。但取決於MySQLWriteFieldData可能是正確的或可能不正確。
  5. 我不知道DirectMySQL是如何工作的。如果它使用原始的TCP/IP與MySQL交談,那麼問題可能就在那裏。例如,它錯誤地處理了一系列數據包。
  6. 最後 - 你得到的錯誤是什麼?你的Delphi版本是什麼?什麼是你的MySQL客戶端和服務器版本?
  7. 等等....

督察,這將是真的很難說,什麼是錯的。爲此,例如,我需要獲得所有的資源,坐在Delphi IDE調試器中,分析許多細節 - 很抱歉,沒時間:)

+0

是的,MySQLDataSize返回delphi數據類型表示單位。 DirectMySQL使用原始的TCP/IP,但是數據已經使用自己的數據格式進行處理。數據在那裏供我們訪問。我已經嘗試過沒有我的課程,並在我的課程中使用它,並且這一切都很完美。我正在使用Delphi 7和MySQL 5.1。錯誤消息是在模塊Project1.exe中的地址00404510處的訪問衝突錯誤。閱讀地址0100A321。 << Project1.exe是我測試組件的程序的名稱。 – eta 2010-12-20 05:28:03

+0

嘗試添加啓用FullDebugMode的FastMM4。可能它會報告一些內存問題。 – 2010-12-20 05:46:46

0

現在通過在末尾添加#0來解決......非常感謝所有回答我的問題的人。

相關問題