首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用TQuery.Locate()函数查找其他匹配项,然后查找第一个匹配项

使用TQuery.Locate()函数查找其他匹配项,然后查找第一个匹配项
EN

Stack Overflow用户
提问于 2018-01-25 21:40:32
回答 2查看 4.8K关注 0票数 3

定位将光标移动到与指定的一组搜索条件匹配的第一行。假设qTQuery组件,它通过两列TAGTAGTEXT连接到数据库。使用下一个代码,我得到了letter a。我想用Locate()函数来获取letter d

代码语言:javascript
复制
 If q.Locate('TAG','1',[loPartialKey]) Then
  begin
    tag60 := q.FieldByName('TAGTEXT');
  end

例如,如果我得到这样的表:

代码语言:javascript
复制
TAG | TAGTEXT
+---+--------+
| 1 | a      |
+---+--------+
| 2 | b      |
+---+--------+
| 3 | c      |
+---+--------+
| 1 | d      |
+---+--------+
| 4 | e      |
+---+--------+
| 1 | f      |
+---+--------+

有没有可能在表中找到第二次出现的第一次?

编辑

我的工作是找到值为1TAG的匹配项(我需要哪个匹配项取决于我得到的参数),我需要遍历表格并从所有TAGTEXT域中获得值,直到我发现TAG字段中的值又是数字1。在这种情况下,数字1代表新段的开始,两个数字1之间的所有值属于一个段。它不必在每个段中有相同的行数。此外,我不被允许在表上做任何更改。

我想我能做的就是创建一个计数器变量,它会在每次遇到值为1TAG时加1。当计数器等于表示出现次数的参数时,我知道我在正确的片段中,我将遍历该片段并获得所需的值。但这可能是一个缓慢的解决方案,我想知道是否有更快的解决方案。

EN

回答 2

Stack Overflow用户

发布于 2018-01-25 23:59:56

出于这样的目的,您需要对使用Locate稍加小心,因为某些TDataSet后代的Locate实现(或底层db访问层)在数据集上构造了一个临时索引。它可以在之后立即丢弃,因此重复调用Locate来迭代给定段的行可能比人们预期的要低得多。

此外,TClientDataSetLocate的每次调用(在其对LocateRecord的内部调用中)构造、使用然后丢弃一个表达式解析器,这对于重复调用来说是大量的开销,特别是当它们完全可以避免的时候。

在任何情况下,最好的方法是确保您的表记录给定行所属的段,如果您的表还没有这样的列,则添加一个类似下面的SegmentID的列:

代码语言:javascript
复制
TAG | TAGTEXT|SegmentID
+---+--------+---------+
| 1 | a      |     1
| 2 | b      |     1
| 3 | c      |     1
| 1 | d      |     2
+---+--------+---------+  // btw, what happened to the 2 missing rows after this one?
| 4 | e      |     2
| 1 | f      |     3
+---+--------+---------+

然后,您可以使用下面这样的代码来迭代片段的行:

代码语言:javascript
复制
procedure IterateSegment(Query : TSomeTypeOfQueryComponent; SegmentID : Integer);
var
  Sql; String;
begin
  Sql := Format('select * from mytable where SegmentID = %d order by Tag', [SegmentID]);
  if Query.Active then
    Query.Close;
  Query.Sql.Text := Sql;

  Query.Open;

  Query.DisableControls;
  try
    while not Query.Eof do begin
      //  process row here
      Query.Next;
    end;
  finally
    Query.EnableControls;
  end;

end;
票数 2
EN

Stack Overflow用户

发布于 2018-01-25 22:14:34

要做到这一点,您有很多选择。

如果你的组件没有提供locateNext,你可以让你的on函数locateNext,比较这个值,然后make next直到找到。

您还可以使用order by带来sql,然后使用locate表示第一个值,并测试下一个值是否与比较匹配。

如果您使用clientDataset,您可以过滤到组件过滤器属性中,或者将IndexFieldNames设置为值排序,而不是先前建议中的sql的"order by“。

您也可以在SQL Where子句上对其进行过滤。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48444277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档