TDataSet Descendant - PullRequest
       17

TDataSet Descendant

0 голосов
/ 20 декабря 2010

У меня есть очень хороший модуль DirectMySQL, который готов к использованию, и я хочу, чтобы он был потомком TDataset, чтобы я мог использовать его с QuickReport, я просто хочу MySQL Query с DirectMySQL, который потомок от TDataset.

Все было хорошо, пока я не попытался получить доступ к большой таблице с 10.000 строк и более.Это было нестабильно, ошибка была непредсказуемой и не всегда отображалась, но, вероятно, это произошло после того, как вы сыграли с другими столами.

Это произошло в GetFieldData (поле: TField; буфер: указатель): логическое значение;который использовал для получения значения поля из строк 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.кто-нибудь есть?Я испытываю недостаток в этом виде раздора.

Ответы [ 2 ]

2 голосов
/ 20 декабря 2010
  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. И так далее ...

СЕЙЧАС, будет очень сложно сказать, что не так. Для этого мне, например, понадобится получить все источники, сесть в отладчик Delphi IDE и проанализировать многие детали происходящего - извините, времени нет:)

0 голосов
/ 22 декабря 2010

Теперь это решено добавлением # 0 в конце строки ... Большое спасибо всем, кто ответил на мою проблему.

...