Delphi不会写最后几行,每个过程都会调用writeToText(a1, a2, ...)

type
  TQuerySQL = class
    public
      Constructor Create;
      Destructor Destroy; override;
      procedure writeToText( plate:String; positionNo:String; newOdometer:String; oldOdometer:String);
  end;

var
  tconnect : TADOConnection;
  tquery : TADOQuery;
  F_Text: TextFile;

implementation

Constructor TQuerySQL.Create;
begin
  AssignFile(F_Text, 'results.txt');
  ReWrite(F_Text);
  tquery := TADOQuery.Create(nil);
  tconnect := TADOConnection.Create(nil);
  tconnect.Close;
  tconnect.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=SOFT20150911;';
  tconnect.ConnectOptions := coConnectUnspecified;
  tconnect.LoginPrompt := False;
  tconnect.Open;
  ShowMessage('starting');
end;

Destructor TQuerySQL.Destroy;
begin
  tquery.Close;
  tquery.Free;
  tconnect.Close;
  tconnect.Free;
  CloseFile(F_Text);
  ShowMessage('finished in destructor');
  inherited Destroy;
end;

procedure TQuerySQL.writeToText( plate:String; positionNo:String; newOdometer:String; oldOdometer:String );
begin
  Write(F_Text, 'UPDATE POSITIONS SET');
  Write(F_Text, ' ODOMETER = '+oldOdometer);
  Write(F_Text, ' WHERE');
  Write(F_Text, ' LABEL = '''+plate+'''');
  Write(F_Text, ' AND POSITIONNO = '''+positionNo+'''');
  Write(F_Text, ' AND ODOMETER = '+newOdometer+';');
  WriteLn(F_Text);
end;

样本输出:

UPDATE POSITIONS SET ODOMETER = 904068,1 WHERE LABEL = '34 XXX 11'and POSITIONNO ='12110126'and ODOMETER = 904092,2;
UPDATE POSITIONS SET ODOMETER = 904068,1 WHERE LABEL = '01 AL 101'and POSITIONNO ='165556'and ODOMETER = 904092,2;
UPDATE POSITIONS SET ODOMETER = 904148,7

最佳答案

也许您的代码的某些部分在F_TextTQuerySQL调用之间从Create类外部访问Destroy变量。

如果在单元的TQuerySQL部分中声明了F_Text,则如果您一起运行多个类var的实例,则会发生相同的情况。

如果没有理由要发生这种情况,则可以考虑将其设置为private

type
  TQuerySQL = class
    private
      F_Text: TextFile;
    public
      Constructor Create;
      Destructor Destroy; override;
      procedure writeToText( plate:String; positionNo:String; newOdometer:String; oldOdometer:String);
  end;


同样适用于:

tconnect : TADOConnection;
tquery : TADOQuery;


为了确保不会在同一单元中错误发生,您还可以考虑将strict关键字添加到该类的private部分。



除了上述内容外,执行除析构函数中释放的对象以外的任务通常不被视为一种好习惯。

我的建议是考虑使用额外的公共方法执行关闭操作,并让析构函数完成其工作。

public
  procedure writeToTextClose;


。 。 。

procedure TQuerySQL.writeToTextClose;
begin
  CloseFile(F_Text);
  tquery.Close;
  tconnect.Close;
  ShowMessage('write to text finished');
end;

destructor TQuerySQL.Destroy;
begin
  tquery.Free;
  tconnect.Free;
  inherited;
end;


可以像这样完成任务:

var
  qSql: TQuerySQL;

. . .

qSql := TQuerySQL.Create;
try

  try
    //here multiple calls to writeToText take place
    qSql.writeToText(a1, a2, ...);

  finally
    //ensure CloseFile(F_Text) at least
    qSql.writeToTextClose;
  end;

finally
  //ensure objects freeing
  qSql.Free;
end;

09-05 05:08