2016-02-05 17 views
0

我有一個函數,我從數據庫中獲取數據,我的測試數據集返回6500行(我從SQLText變量中提取格式化的SQL語句並將其作爲測試運行),但是當我運行下面的代碼Eof從不觸發,我已經看到超過10萬行的輸入。Eof not triggering

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 +行都被處理後也結束。

回答

8

Open()將光標放在第一條記錄上並相應地設置Eof。你是不是叫Next(),使光標移動到下一個記錄和更新Eof,所以你一遍又一遍的處理相同的記錄:

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

在一個側面說明,你應該使用參數化查詢代替一個格式化的SQL查詢字符串。在DB上更安全,更快速,更高效:

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;