如何转到ado.locate(Delphi)结果中的最后一条记录

时间:2017-12-31 22:21:54

标签: delphi ado

我通过此代码找到了一些记录:

ADOQuery1.Locate('field1',ADOQuery2.FieldByName('field2').Value,[])  

如何转到最后一条记录?

2 个答案:

答案 0 :(得分:6)

您有很多选择。最好的取决于你在问题中没有提到的很多考虑因素。我将提供非常简短的概述选项,以避免这种情况变得过于宽泛"。它取决于您做出选择并弄清楚细节。如果你遇到困难,你可以提出一个更具体的新问题。

使用Locate

如果您的数据集 已排序 ,那么涉及Locate的解决方案仅 可行您正在搜索的字段。

显然,您的搜索值不是唯一键。因此,我猜测您正在尝试在按其他唯一字段排序的数据中找到与搜索关键字匹配的最后一行。 (否则 last 的概念毫无意义。)

所以很可能这不适合你;除非您的数据按搜索字段的复合键排序,后跟唯一键。

方法很简单:向前导航,直到找到搜索值不匹配的行,然后回溯1行。

if not DataSet.Locate(SearchField, SearchValue, []) then
  { handle not found case as desired }
else
begin
  while (not DataSet.Eof) and (DataSet.FieldByName(SearchField).Value = SearchValue) do
    DataSet.Next;

  { Watch out for case that last row in dataset matches search value }
  if (DataSet.FieldByName(SearchField).Value <> SearchValue) then
    DataSet.Prior;
end;

实施您自己的搜索

这是直截了当的,永远有效。但它效率低,具有O(n)复杂度。因此不建议使用大型数据集。

DataSet.Last;
while (not DataSet.Bof) and (DataSet.FieldByName(SearchField).Value <> SearchValue) do
  DataSet.Prior;

注意: 为了反映Locate的行为,建议您使用此方法来处理未找到匹配项的情况所有。在这种情况下,活动记录不应被无意中更改为搜索的副作用。

使用过滤

显然,此解决方案取决于过滤数据集是否适合您的其余代码。但这是一个相当简单的选择,并且超出了本答案范围的依赖因素,它可能比以前的选项更具性能。

DataSet.Filtered := False;
{ The next line may be a little tricky.
  Ensure the filter string is appropriate for the data-types involved. }
DataSet.Filter := '<string of the form SearchField = SearchValue>';
DataSet.Filtered := True;
DataSet.Last;

请参阅Filter属性的文档。

注意: 建议您采取预防措施,不要冗余地设置过滤器。

使用主 - 明细关系

包含此选项是因为您的问题代码表明SearchValue来自另一个数据集的活动记录。您正在使用ADO,因此您可以使用此选项。

DataSet.MasterSource := <Appropriate DataSource>;
DataSet.MasterFields := SearchField;
DataSet.Last;

请参阅master-detail relationshipsADO MasterFields上的文档。

将工作卸载到RDBMS

最后,值得考虑使用存储过程直接从数据库获取所需信息。优点是服务器可以利用可用的索引,并有可能提供最高性能的选项。但是,很多时候,很大程度上取决于您申请的细节。

以下行中的查询可以构成存储过程的基础。

select  MAX(UniqueField) as RowKey
from    Table
where   SearchField = SearchValue

然后调用存储过程,并使用其结果查找所需的行。

DataSet.Locate(UniqueField, RowKey, []);

注意: 如果不存在具有SearchValue的行,请不要忘记返回NULL的存储过程。

一般免责声明

以上所有代码都非常简短,仅供说明之用。在许多情况下,强大的实现需要额外的代码 例如。可能需要DisableControls并再次启用它们。

注意: 通过以上方式了解数据集中数据的实际排序非常重要。如果不考虑这一点,可能会导致行为不正确。 如果您的数据集未按UniqueKey排序,即使是最后一个选项也可能表现出比预期更差的效果。

答案 1 :(得分:0)

如果您的表格有自动增量标识字段,则可以执行此操作

adoquery1.sql.clear;
adoquery1.sql.add('select top 1 * from  yourtablename where field1=value1 and filed2=value2 order by yourAIcolums desc')
adoquery1.execsql;

value1和value2是您想要的值。将它们作为参数传递或将它们放在命令文本中 这样你只需要你想要的行,而不需要循环