在查询/“TDataset”的“打开”之后是否应该首先调用`First`?

时间:2016-06-13 11:16:52

标签: delphi dataset

我习惯在迭代查询结果时总是调用First()

Qry.Open;
Qry.First;
while not Qry.Eof do
begin
    //do something
    Qry.Next;
end;

是否有理由First()之后不会自动调用Open()

或者问另一种方式:我们使用某种DB访问抽象类。将First()的调用包含在我们的Open()例程中是不是一个好主意?

4 个答案:

答案 0 :(得分:6)

您正在展示为什么明确需要First的完美示例:由于您在迭代后没有关闭数据集,因此对此代码序列的新调用将不会真正打开数据集。它仍处于打开状态,对Open的调用无声无效。因此,需要First才能使迭代工作。

严格地说,它归结为Hilario所说:迭代前需要First

答案 1 :(得分:2)

对于大多数(所有)DataSet衍生产品,如果先前已关闭数据集,则在打开后调用First是完全冗余的。

但是,如果DataSet先前已经打开而没有被关闭,那么Open将不执行任何操作(因为DataSet已经打开),并且First将确保DataSet在打开后位于预期位置(在BOF处)

答案 2 :(得分:1)

我不认为' First'需要在“打开”后调用。一个数据集。 需要在迭代之前调用它,以确保它将访问数据集上的所有记录。

答案 3 :(得分:1)

在遥远的过去(BDE日),我记得读过或听说打开查询的规范并没有坚持将查询放在数据集的开头。但是,我检查的所有查询组件都在代码中的某处包含了first()。

我曾经将查询组件子类化为包含第一个(),但现在不要认为它是必要的。我用过的所有查询都在第一条记录中打开。

跟踪ADO查询的代码open()来到这段代码,这些代码看起来会在打开后将数据集保留在第一个位置。

procedure TCustomADODataSet.InternalFirst;
begin
  if not Recordset.BOF then
  begin
    Recordset.MoveFirst;
    if Recordset.Supports(adMovePrevious) and not Recordset.BOF then
      Recordset.MovePrevious;
  end;
end;