Delphi 如何在运行时使用TFDQuery的RecsSkip和RecsMax属性

Delphi 如何在运行时使用TFDQuery的RecsSkip和RecsMax属性,delphi,firedac,delphi-10.2-tokyo,skip-take,Delphi,Firedac,Delphi 10.2 Tokyo,Skip Take,我在TFDQuery中寻找一个跳过并执行选择。 我找到的属性是.FetchOptions.RecsSkip和.FetchOptions.RecsMax。我使用东京10.2.3和数据库火鸟3 我在运行时进行查询,并希望在5处获取开始记录,然后获取接下来的8条记录 我喜欢这样: 结果不会跳过前5条记录 var qryTest: TFDQuery; begin qryTest:= TFDQuery.Create(self); qryTest.Connection := self.FDConne

我在TFDQuery中寻找一个跳过并执行选择。 我找到的属性是.FetchOptions.RecsSkip和.FetchOptions.RecsMax。我使用东京10.2.3和数据库火鸟3

我在运行时进行查询,并希望在5处获取开始记录,然后获取接下来的8条记录

我喜欢这样:

结果不会跳过前5条记录

var
  qryTest: TFDQuery;
begin
 qryTest:= TFDQuery.Create(self);
 qryTest.Connection := self.FDConnection;

 qryTest.sql.Text:= ' select * from salutationdescriptions order by ID';
 qryTest.Disconnect();
 qryTest.FetchOptions.RecsSkip:= 5;
 qryTest.FetchOptions.RecsMax:= 8;
 qryTest.Open();
  qryItem.Close;
  qryItem.Disconnect();
  qryItem.FetchOptions.RecsSkip:= 5;
  qryItem.FetchOptions.RecsMax:= 8;
  qryItem.Open();
  qryItem.Close;
  qryItem.sql.Text:= ' select * from salutationdescriptions order by ID';
  qryItem.Disconnect();
  qryItem.FetchOptions.RecsSkip:= 5;
  qryItem.FetchOptions.RecsMax:= 8;
  qryItem.Open();
但这给出了前8条记录。不会跳过前5条记录

好的,我选择了相同的选项,但现在我在设计时设置了TFQQuery(表单上的组件),并在组件中添加选择“select*from SALLATIONDescriptions order by ID”

运行代码:

跳过前5条记录

var
  qryTest: TFDQuery;
begin
 qryTest:= TFDQuery.Create(self);
 qryTest.Connection := self.FDConnection;

 qryTest.sql.Text:= ' select * from salutationdescriptions order by ID';
 qryTest.Disconnect();
 qryTest.FetchOptions.RecsSkip:= 5;
 qryTest.FetchOptions.RecsMax:= 8;
 qryTest.Open();
  qryItem.Close;
  qryItem.Disconnect();
  qryItem.FetchOptions.RecsSkip:= 5;
  qryItem.FetchOptions.RecsMax:= 8;
  qryItem.Open();
  qryItem.Close;
  qryItem.sql.Text:= ' select * from salutationdescriptions order by ID';
  qryItem.Disconnect();
  qryItem.FetchOptions.RecsSkip:= 5;
  qryItem.FetchOptions.RecsMax:= 8;
  qryItem.Open();
我得到的结果还可以。这将跳过前5条记录。 当我添加qryItem.sql.text时,它不会跳过前5条记录

这不会跳过前5条记录

var
  qryTest: TFDQuery;
begin
 qryTest:= TFDQuery.Create(self);
 qryTest.Connection := self.FDConnection;

 qryTest.sql.Text:= ' select * from salutationdescriptions order by ID';
 qryTest.Disconnect();
 qryTest.FetchOptions.RecsSkip:= 5;
 qryTest.FetchOptions.RecsMax:= 8;
 qryTest.Open();
  qryItem.Close;
  qryItem.Disconnect();
  qryItem.FetchOptions.RecsSkip:= 5;
  qryItem.FetchOptions.RecsMax:= 8;
  qryItem.Open();
  qryItem.Close;
  qryItem.sql.Text:= ' select * from salutationdescriptions order by ID';
  qryItem.Disconnect();
  qryItem.FetchOptions.RecsSkip:= 5;
  qryItem.FetchOptions.RecsMax:= 8;
  qryItem.Open();
这不会跳过前5条记录

我必须在属性中设置一些内容吗

我想在运行时使用RecsSkip和RecsMax。有什么建议吗

发现问题

在SQL.Text中,我必须以“选择…”开头。。。
'和选择之间没有空格正如您已经发现的,问题在于SQL命令的前导空格。这是因为命令生成器不考虑前导命令空间。有这样一个代码(经过修改和广泛简化,以供我解释):

在这里,您可能会看到问题所在。仅当从查询命令文本指定的FCommandText字段由SELECT单词开始时,命令生成器才会返回DBMS的本机LIMIT命令。这不是您的情况(由于前导空格),因此生成器按原样返回命令

这是我报告的FireDAC bug。由于有更多这样的检查,我认为最简单的修复方法是直接在其构造函数中修剪SQL命令,如:

constructor TFDPhysCommandGenerator.Create(const ACommand: IFDPhysCommand);
begin
  ...
  FCommandText := Trim(ACommand.SQLText);
  ...
end;

因此,现在轮到EMBT如何解决这个问题。

无法复制。在更改准备好的查询对象调用的获取选项之前,请先断开连接。但这似乎不是您的情况,或者当您更改实际代码中的获取选项时,查询对象是否已准备好?哦,在任何情况下,元组都将以不可预测的顺序获取,只要您不在DBMS端对它们进行排序(使用
orderby
子句)。A添加了断开连接,但不起作用东京10.2.3?是的,我使用10.2.3还添加了“orderby”。不要在运行时跳过,我会在深入的风险分析后用问题编号更新帖子。不客气!谢谢你找到这个问题!我正要开始分析并报告(现在只需要一些咖啡:)@Victoria:干得好,+1。Tbh,这个问题让我感到沮丧的是,即使像FD这样的高质量库也依赖于类似于
if…CompareText(Copy(FCommandText,1,6),'SELECT')=0
这样的黑客,而不是使用适当的SQL解析器来进行分析。毕竟,SQL中的“S”代表“Structured”,因此分析人员应该能够处理查询中的嵌套子句以及顶级构造,如SELECT…@MartynA,拥有一个就好了!Ravaut123,报告为。建议的修补程序应该是无害的(我希望:)对RSP-20403进行投票