2010-12-20 4 views
0

사용할 준비가 된 아주 좋은 DirectMySQL 장치가 있습니다. 따라서 TDataset의 자손이되어서 QuickReport와 함께 사용할 수 있습니다. TDataset의 자손 인 DirectMySQL을 사용하여 MySQL Query를 원합니다.TDataSet Descendant

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; 

내 생각 엔 그것은 메모리와 관련된 문제입니다이다, 코드입니다.

스택입니다. 누구든지 도울 수 있니? 또한 availlable 하위 함수를 나열하는 TDataset 설명서와이를 사용하는 방법 또는 TDataset의 자손을 만드는 방법이 필요합니다. 누구든지 가지고있어? 나는 이런 종류의 증감이 없다.

+0

methinks - TL; 또한 TDataSet 문서 및 소스는 Delphi와 함께 제공됩니다. 어쨌든, MySQL은 큰 행 집합을 처리 할 수 ​​없다. –

답변

2
  1. GetFieldData에는 UpdateCursorPos 및 Resync 호출을 사용할 수 없습니다. 그렇지 않으면 예기치 않은 오류가 발생할 수 있습니다.
  2. FD : = oRecordset.FieldDef (I) ... FD : = oRecordset.FieldDef (I); - 이상하게 보입니다. 두 번째 부탁은 필요하지 않습니다.
  3. ... 마지막으로 지역 변수 재설정이 필요하지 않습니다.
  4. MySQLDataSize가 무엇을 반환하는지 잘 모르겠습니다. 예를 들어, MySQLDataSize는 델파이 데이터 형식 표현 단위로 크기를 반환하거나 MySQL이 반환하는 데이터의 길이를 반환 할 수 있습니다. 하지만 MySQLWriteFieldData에 따라 정확하거나 그렇지 않을 수도 있습니다.
  5. DirectMySQL의 작동 방식을 잘 모릅니다. 원시 TCP/IP를 사용하여 MySQL과 통신하는 경우 문제가있을 수 있습니다. 예를 들어, 잘못 패킷 시퀀스를 처리합니다.
  6. 마지막으로 - 오류는 무엇입니까? 델파이 버전은 무엇입니까? 귀하의 MySQL 클라이언트 및 서버 버전은 무엇입니까? 말을 정말 힘들 것
  7. 등등 ....

IOW은 잘못된 것입니다. 그렇게하려면, 예를 들어, 모든 소스를 가져 와서 Delphi IDE 디버거에 앉아서 무슨 일이 일어나고 있는지 세부 사항을 분석해야합니다 :

+0

예, MySQLDataSize는 델파이 데이터 형식 표현 단위를 반환합니다. DirectMySQL은 TCP/IP raw를 사용하지만 데이터는 자체 데이터 형식을 사용하여 처리되었습니다. 우리가 액세스 할 수있는 데이터가 있습니다. 나는 수업없이 시험해 보았고 그것을 나의 프로그램에서 사용했다. 그리고 그것은 모두 완벽하게 작동한다. Delphi 7과 MySQL 5.1을 사용하고 있습니다. 오류 메시지는 >> Project1.exe 모듈의 주소 00404510에있는 >> 액세스 위반 오류입니다. 주소 0100A321 읽기. << Project1.exe는 구성 요소를 테스트하기 위해 만드는 프로그램의 이름입니다. – eta

+0

FullDebugMode가 설정된 FastMM4를 추가하십시오. 아마 그것은 약간의 기억 문제를보고 할 것입니다. –

0

끝 부분에 # 0을 추가하여 해결되었습니다. 라인의 ... 내 문제에 대답 모든 사람에게 너무 고마워.

관련 문제