如何限制 TFDMemTable 中的记录数?
How to limit number of records in TFDMemTable?
我有一个 TFDMemTable,里面装满了数千条记录。有没有办法限制前 50 个结果记录?
我试过使用:
FDMemTable.FetchOptions.RecsSkip := 0;
FDMemTable.FetchOptions.RecsMax := 50;
FDMemTable.Open;
但是还是不行,数据没变。
我希望@Victoria 能够向您展示一个更好更通用的
方式,但至少有两种方法可以做到这一点:
使用 FD 的 FDLocalSQL 功能将 FDMemTable 的前 X 行复制到,比如说,
一个 FDQuery,然后将它们复制回您的 FDMemTable。
对 FDMemTable 应用过滤器以过滤掉其他记录,使用 FDBatchMove
将 X 记录复制到第二个 FDMemTable,然后将它们复制回原来的
FDMemTable.
要实现其中的第一个,请将以下组件添加到您的 form/datamodule:
FDLocalSQL1: TFDLocalSQL;
FDConnection1: TFDConnection;
FDQuery1: TFDQuery;
FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
然后执行如下代码:
procedure TForm3.CopyData1;
begin
FDConnection1.DriverName := 'SQLite';
FDConnection1.Connected := True;
FDLocalSQL1.Connection := FDConnection1;
FDLocalSQL1.DataSets.Add(FDMemTable1); // this is the source dataset
FDLocalSQL1.Active := True;
FDQuery1.SQL.Text := 'select * from FDMemTable1 order by ID limit 5'; // ID being an Integer field of the FDMemTable
FDQuery1.Active := True;
FDMemTable1.Close;
FDMemTable1.Data := FDQuery1.Data; // Re-opens FDMemTable 1, which now contains only the first X records
end;
FD 的 LocalSQL 使用 Sqlite 来完成它的工作。 Sqlite 中的等价功能 SQL
to "Select Top X ..." 是它的限制子句。
使用 LocalSQL 完成任务的一个优势当然是因为 LocalSQL
支持order by,你可以通过它来判断哪些(top)X记录被保留了。
batchmove 方法需要的代码少一些,但需要您有一种识别方法
使用过滤器表达式的前 X 条记录。使用 ID 字段的示例可能是
procedure TForm3.CopyData2;
begin
FDMemTable1.Filter := 'ID <=50';
FDMemTable1.Filtered := True;
FDBatchMove1.Execute; // move data from FDMemTable1 to FDMemTable2;
FDMemTable1.Close;
FDMemTable1.Data := FDMemTable2.Data; // Re-opens FDMemTable 1, which now contains only the first X records
end;
顺便说一句,你说
I have a TFDMemTable filled with thousands of records. I
我认为您尝试过的方法的问题可能是当您在 FDMemTable 中拥有记录时,以您尝试的方式尝试限制它们的数量为时已晚。 *)
我有一个 TFDMemTable,里面装满了数千条记录。有没有办法限制前 50 个结果记录?
我试过使用:
FDMemTable.FetchOptions.RecsSkip := 0;
FDMemTable.FetchOptions.RecsMax := 50;
FDMemTable.Open;
但是还是不行,数据没变。
我希望@Victoria 能够向您展示一个更好更通用的 方式,但至少有两种方法可以做到这一点:
使用 FD 的 FDLocalSQL 功能将 FDMemTable 的前 X 行复制到,比如说, 一个 FDQuery,然后将它们复制回您的 FDMemTable。
对 FDMemTable 应用过滤器以过滤掉其他记录,使用 FDBatchMove 将 X 记录复制到第二个 FDMemTable,然后将它们复制回原来的 FDMemTable.
要实现其中的第一个,请将以下组件添加到您的 form/datamodule:
FDLocalSQL1: TFDLocalSQL;
FDConnection1: TFDConnection;
FDQuery1: TFDQuery;
FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
然后执行如下代码:
procedure TForm3.CopyData1;
begin
FDConnection1.DriverName := 'SQLite';
FDConnection1.Connected := True;
FDLocalSQL1.Connection := FDConnection1;
FDLocalSQL1.DataSets.Add(FDMemTable1); // this is the source dataset
FDLocalSQL1.Active := True;
FDQuery1.SQL.Text := 'select * from FDMemTable1 order by ID limit 5'; // ID being an Integer field of the FDMemTable
FDQuery1.Active := True;
FDMemTable1.Close;
FDMemTable1.Data := FDQuery1.Data; // Re-opens FDMemTable 1, which now contains only the first X records
end;
FD 的 LocalSQL 使用 Sqlite 来完成它的工作。 Sqlite 中的等价功能 SQL to "Select Top X ..." 是它的限制子句。
使用 LocalSQL 完成任务的一个优势当然是因为 LocalSQL 支持order by,你可以通过它来判断哪些(top)X记录被保留了。
batchmove 方法需要的代码少一些,但需要您有一种识别方法 使用过滤器表达式的前 X 条记录。使用 ID 字段的示例可能是
procedure TForm3.CopyData2;
begin
FDMemTable1.Filter := 'ID <=50';
FDMemTable1.Filtered := True;
FDBatchMove1.Execute; // move data from FDMemTable1 to FDMemTable2;
FDMemTable1.Close;
FDMemTable1.Data := FDMemTable2.Data; // Re-opens FDMemTable 1, which now contains only the first X records
end;
顺便说一句,你说
I have a TFDMemTable filled with thousands of records. I
我认为您尝试过的方法的问题可能是当您在 FDMemTable 中拥有记录时,以您尝试的方式尝试限制它们的数量为时已晚。 *)