TDataSet Descendant

时间:2010-12-20 00:35:09

标签: mysql delphi delphi-7

我有一个非常好的DirectMySQL单元,可以使用它,我希望它是一个TDataset后代,所以我可以将它与QuickReport一起使用,我只想要使用DirectMySQL的MySQL查询,后者来自TDataset。

一切都很好,直到我试图访问一个包含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下载。谁有他们?我缺乏这种doumentation。

2 个答案:

答案 0 :(得分:2)

  1. GetFieldData无法进行UpdateCursorPos和Resync调用。否则,您可能会收到不可预测的错误。
  2. FD:= oRecordset.FieldDef(I)... FD:= oRecordset.FieldDef(I); - 看起来很奇怪。不需要第二次分配。
  3. 最后......不需要重置局部变量。
  4. 我不知道是什么返回MySQLDataSize。例如,MySQLDataSize可以返回Delphi数据类型表示单元中的大小,或者可以返回MySQL返回的数据长度。但取决于MySQLWriteFieldData可能是正确的,也可能不是。
  5. 我不知道DirectMySQL是如何工作的。如果它使用原始TCP / IP与MySQL通信,则可能存在问题。例如,它错误地处理了一系列数据包。
  6. 最后 - 你得到的错误是什么?你的Delphi版本是什么?你的MySQL客户端和服务器版本是什么?
  7. 依旧......
  8. 呃,这真的很难说,出了什么问题。为此,我需要获取所有资源,坐在Delphi IDE调试器中并分析正在发生的事情的许多细节 - 抱歉,没时间:)

答案 1 :(得分:0)

现在通过在行尾添加#0解决了...非常感谢所有回答我问题的人。