Eof不触发

Eof not triggering

我有一个从数据库获取数据的函数,我的测试数据集 returns 6500 行(我从 SQL 文本变量和 运行 作为测试),但是当我 运行 以下代码 Eof 永远不会触发时,我已经看到导入了超过 100k 行。

ADOQuery := TADOQuery.Create(nil);
ADOQuery.ConnectionString := CONNECT_STRING;

// Build SQL Query 
SQLText :=   Format( 'Select  Temp.Serial, Temp.QCSample , Temp.Scrap , Temp.StationID , Temp.Defect , Temp.AddData , Temp2.Serial as Parent_Serial ' +
      'from TAB_ELEMENT as Temp ' + 

      'left join TAB_ELEMENT as Temp2 on  Temp.Parent_Id = Temp2.Element_Id ' + 
      'where Temp.Batch_ID = %d    and Temp.StationID = 0 ',[iSearchID]);

ADOQuery.SQL.Clear;   // Clear query of garbage values
ADOQuery.SQL.Text := SQLText; // Add query text to query module
ADOQuery.Open; 

// Handle Results
iIndexPos := 0; 
tDataImport.BeginUpdate;  

while not ADOQuery.Eof do
begin
    tDataImport.Items[iIndexPos].Serial := ADOQuery.FieldByName('Serial').AsString;
    tDataImport.Items[iIndexPos].QCStatus := ADOQuery.FieldByName('QCSample').AsBoolean;
    tDataImport.Items[iIndexPos].Scrap := ADOQuery.FieldByName('Scrap').AsInteger;
    tDataImport.Items[iIndexPos].StationID := ADOQuery.FieldByName('StationID').AsInteger;
    tDataImport.Items[iIndexPos].Defect := ADOQuery.FieldByName('Defect').AsBoolean;
    tDataImport.Items[iIndexPos].AddData := ADOQuery.FieldByName('AddData').AsString;
    tDataImport.Items[iIndexPos].ParentSerial := ADOQuery.FieldByName('Parent_Serial').AsString;

    inc(iIndexPos);
end;

因此,在夏季 运行 使用这些参数进行此查询时,我希望有 6500 行,当我 运行 时,即使处理了 100k+ 行,它也永远不会结束。

Open() 将光标放在第一条记录上并相应地设置 Eof。您没有调用 Next() 将光标前进到下一条记录并更新 Eof,因此您正在一遍又一遍地处理同一条记录:

ADOQuery.Open; 
while not ADOQuery.Eof do
begin
  //...
  ADOQuery.Next; // <-- add this!
end;

附带说明一下,您应该使用 参数化查询 而不是格式化的 SQL 查询字符串。在数据库上更安全、更快、更高效:

ADOQuery := TADOQuery.Create(nil);
ADOQuery.ConnectionString := CONNECT_STRING;

ADOQuery.SQL.Text := 'Select  Temp.Serial, Temp.QCSample , Temp.Scrap , Temp.StationID , Temp.Defect , Temp.AddData , Temp2.Serial as Parent_Serial ' +
  'from TAB_ELEMENT as Temp ' + 
  'left join TAB_ELEMENT as Temp2 on  Temp.Parent_Id = Temp2.Element_Id ' + 
  'where Temp.Batch_ID = :iSearchID and Temp.StationID = 0 ';

with ADOQuery.Parameters.ParamByName('iSearchID') do
begin
  DataType := ftInteger;
  Value := iSearchID;
end;

ADOQuery.Open; 
try
  iIndexPos := 0; 
  tDataImport.BeginUpdate;  
  try
    while not ADOQuery.Eof do
    begin
      tDataImport.Items[iIndexPos].Serial := ADOQuery.FieldByName('Serial').AsString;
      tDataImport.Items[iIndexPos].QCStatus := ADOQuery.FieldByName('QCSample').AsBoolean;
      tDataImport.Items[iIndexPos].Scrap := ADOQuery.FieldByName('Scrap').AsInteger;
      tDataImport.Items[iIndexPos].StationID := ADOQuery.FieldByName('StationID').AsInteger;
      tDataImport.Items[iIndexPos].Defect := ADOQuery.FieldByName('Defect').AsBoolean;
      tDataImport.Items[iIndexPos].AddData := ADOQuery.FieldByName('AddData').AsString;
      tDataImport.Items[iIndexPos].ParentSerial := ADOQuery.FieldByName('Parent_Serial').AsString;
      inc(iIndexPos);
      ADOQuery.Next; 
    finally
      tDataImport.EndUpdate;  
    end;
  end;
finally
  ADOQuery.Close; 
end;