首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TDataSet后代

TDataSet后代
EN

Stack Overflow用户
提问于 2010-12-20 08:35:09
回答 2查看 408关注 0票数 0

我有一个非常好的DirectMySQL单元,它已经准备好可以使用了,我希望它是TDataset的后代,这样我就可以在QuickReport中使用它,我只想要MySQL查询和DirectMySQL,它是TDataset的后代。

一切都很好,直到我尝试访问一个有10.000行或更多行的大表。它是不稳定的,错误是不可预测的,并不总是显示出来,但它很可能发生在你玩了其他桌子之后。

它发生在GetFieldData( field : TField;Buffer: Pointer):boolean;中,它用于从MySQL行中获取字段值。

这是代码,

代码语言:javascript
复制
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的后代。有人拿到了吗?我没有这种湿润的感觉。

EN

回答 2

Stack Overflow用户

发布于 2010-12-20 12:36:44

  1. GetFieldData不能有UpdateCursorPos和Resync调用。否则你可能会得到不可预测的错误。
  2. FD := oRecordset.FieldDef(I) ...FD := oRecordset.FieldDef(I);-看起来很奇怪。第二个任务不是needed.
  3. finally ...不需要重置局部变量。
  4. 我不知道什么会返回MySQLDataSize。例如,MySQLDataSize可以返回以Delphi数据类型表示单位表示的大小,也可以返回由MySQL返回的数据长度。但取决于MySQLWriteFieldData可能是正确的也可能不是。
  5. 我不知道DirectMySQL是如何工作的。如果它使用原始TCP/IP与MySQL通信,那么问题可能就在那里。例如,它错误地处理了一系列数据包。
  6. 和最后-您收到的错误是什么?你的Delphi版本是什么?您的MySQL客户端和服务器版本是什么?
  7. 等....

哦,这真的很难说,出了什么问题。例如,要做到这一点,我将需要获得所有源代码,坐在Delphi IDE调试器前分析正在发生的事情的许多细节-对不起,没有时间:)

票数 2
EN

Stack Overflow用户

发布于 2010-12-22 13:52:23

现在可以通过在行尾添加#0来解决这个问题。非常感谢所有回复我问题的人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4486007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档