定位将光标移动到与指定的一组搜索条件匹配的第一行。假设q
是TQuery
组件,它通过两列TAG
和TAGTEXT
连接到数据库。使用下一个代码,我得到了letter a
。我想用Locate()
函数来获取letter d
。
If q.Locate('TAG','1',[loPartialKey]) Then
begin
tag60 := q.FieldByName('TAGTEXT');
end
例如,如果我得到这样的表:
TAG | TAGTEXT
+---+--------+
| 1 | a |
+---+--------+
| 2 | b |
+---+--------+
| 3 | c |
+---+--------+
| 1 | d |
+---+--------+
| 4 | e |
+---+--------+
| 1 | f |
+---+--------+
有没有可能在表中找到第二次出现的第一次?
编辑
我的工作是找到值为1
的TAG
的匹配项(我需要哪个匹配项取决于我得到的参数),我需要遍历表格并从所有TAGTEXT域中获得值,直到我发现TAG字段中的值又是数字1。在这种情况下,数字1代表新段的开始,两个数字1之间的所有值属于一个段。它不必在每个段中有相同的行数。此外,我不被允许在表上做任何更改。
我想我能做的就是创建一个计数器变量,它会在每次遇到值为1
的TAG
时加1。当计数器等于表示出现次数的参数时,我知道我在正确的片段中,我将遍历该片段并获得所需的值。但这可能是一个缓慢的解决方案,我想知道是否有更快的解决方案。
发布于 2018-01-25 23:59:56
出于这样的目的,您需要对使用Locate
稍加小心,因为某些TDataSet
后代的Locate
实现(或底层db访问层)在数据集上构造了一个临时索引。它可以在之后立即丢弃,因此重复调用Locate
来迭代给定段的行可能比人们预期的要低得多。
此外,TClientDataSet
为Locate
的每次调用(在其对LocateRecord
的内部调用中)构造、使用然后丢弃一个表达式解析器,这对于重复调用来说是大量的开销,特别是当它们完全可以避免的时候。
在任何情况下,最好的方法是确保您的表记录给定行所属的段,如果您的表还没有这样的列,则添加一个类似下面的SegmentID
的列:
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
+---+--------+---------+
然后,您可以使用下面这样的代码来迭代片段的行:
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;
发布于 2018-01-25 22:14:34
要做到这一点,您有很多选择。
如果你的组件没有提供locateNext,你可以让你的on函数locateNext,比较这个值,然后make next直到找到。
您还可以使用order by带来sql,然后使用locate表示第一个值,并测试下一个值是否与比较匹配。
如果您使用clientDataset,您可以过滤到组件过滤器属性中,或者将IndexFieldNames设置为值排序,而不是先前建议中的sql的"order by“。
您也可以在SQL Where子句上对其进行过滤。
https://stackoverflow.com/questions/48444277
复制相似问题