我有一个简单的查询,返回以下行:
Name Value
Peter 1
Peter 2
Peter 3
John 1
John 2
应用过滤器:
ADO.Filter := 'Name="John"';
ADO.Filtered := True; // Now, its only 2 rows in dataset
ADO.Locate('Value', 2);
光标应指向“John 2”,但它指向“Peter 2”(由滤镜过滤掉)。并且定位返回True。
尝试使用Delphi 7,Rad studio XE 6.看来这个错误在过去的15年里一直存在 任何解决方案?
答案 0 :(得分:6)
TCustomADODataSet.Locate
的问题在于它在内部使用Recordset.Clone
并尝试在克隆记录集中找到记录,而不将过滤器设置为克隆记录集(请参阅ADODB TCustomADODataSet.LocateRecord
)。
来自文档中的备注:
原始Recordset的Filter属性(如果有)不会 应用于克隆。设置新Recordset的Filter属性 过滤结果。复制任何现有Filter的最简单方法 value是直接赋值,如下所示。 rsNew.Filter = rsOriginal.Filter设置新创建的克隆的当前记录 到了第一张唱片。
我一直在使用我自己的简单Locate
函数来过滤ADO数据集:基本上,存储当前书签,移动到第一个记录并迭代DataSet直到找到匹配项。如果找不到匹配项,则恢复上一个书签
贝娄是一个非常有限的实现,对我有用(很多完美的解决方案):
class function TData.Locate(DataSet: TDataSet; const KeyFields: string;
const KeyValues: Variant; Options: TLocateOptions): Boolean;
{ a very simple Locate function - todo: TLocateOptions & multiple KeyFields/KeyValues }
var
BM: TBookmarkStr;
begin
Result := False;
if DataSet.IsEmpty then Exit;
BM := DataSet.Bookmark;
DataSet.DisableControls;
try
DataSet.First;
while not DataSet.Eof do
begin
if DataSet.FieldByName(KeyFields).Value = KeyValues then
begin
Result := True;
Break;
end;
DataSet.Next;
end;
if not Result then DataSet.Bookmark := BM;
finally
DataSet.EnableControls;
end;
end;
另一个选项是修补ADODB.pas TCustomADODataSet.LocateRecord
并设置FLookupCursor.Filter
以匹配当前数据集过滤器。只要将ADODB.pas修补为项目文件夹中的新副本,就可以使用此选项。
另一种选择是使用TCustomADODataSet.Recordset.Find
方法(另请参阅:How to use a RecordSet.Find with TADOQuery?)。
答案 1 :(得分:0)
试试这个:
ADO.Filter := 'Name=' + QuotedStr('John');
ADO.Filtered := True; // Now, its only 2 rows in dataset
ADO.Locate('Value',2,[]);
Locate函数的第三个参数用于定位选项,我在上面的例子中留空了。您可以在此处阅读 http://docwiki.embarcadero.com/RADStudio/XE7/en/Using_Locate和http://docwiki.embarcadero.com/Libraries/XE7/en/Data.DB.TDataSet.Locate