Delphi Rio 10.3.2 Android FireDac SQLITE 无法打开查询 - 相同的代码适用于 Delphi Tokyo 和相同的 android 设备
Delphi Rio 10.3.2 Android FireDac SQLITE unable to open query - same code worked with Delphi Tokyo with same android device
下面是使用 Delphi Tokyo 编译时完美运行的非常简单的代码:
procedure TfData.DataSend(Memo : TMemo);
var SelectQuery : string;
begin
// Query simplified, more fields are retreived in original code, but same problem with simple query
SelectQuery := 'SELECT NUM as "NUM::TEXT" FROM TRACE WHERE DT_SENT is null ORDER BY DT_TRACE';
YsDbQuerySelect.SQL.Clear;
YsDbQuerySelect.SQL.Add(SelectQuery);
YsDbQuerySelect.Prepare;
try
YsDbQuerySelect.Open;
if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
YsDbQuerySelect.First; // ********** Exception !
while not YsDbQuerySelect.eof do begin
// making a file... code removed, not relevant
YsDbQuerySelect.Next;
end;
YsDbQuerySelect.Close;
end
else begin
YsDbQuerySelect.Close;
MesInfo('No data to send');
end;
except
on e : exception do begin
// Exception displays the annoying error
MesError(e.Message + ' SLQ : ' + SelectQuery);
end;
end;
end;
使用 Tokyo 10.3.2 编译时,同一真实 android 设备 (Zebra TC25) 上的相同简单代码 运行 不再有效。 "RecordCount" 方法 returns 6,然而,"First" 方法触发异常:类似于 "Cannot perform this operation on a closed dataset",原始消息是法语的:"Impossible d'effecteur cette opération sur un ensemble de données fermé"
我无法理解 "RecordCount" 如何在 "First" 触发此异常时 return 某些东西。而数据库中确实有6条记录。我也删除了然后重新创建了它们。同样的错误。
我尝试使用一些选项(获取选项等)但没有任何效果。这真的很烦人。
另请注意,其他操作可在同一个 SQLite 数据库上正常运行。该设备能够使用 TDFCommand 添加和删除记录,并使用 TDataSource 显示它们。只有 TDFQuery 遇到错误。
我删除了 TDFQuery 组件,然后删除了一个新组件。这有点奇怪,但它正在工作。我认为与 Delphi Rio 无关,但与损坏的文件有关?
理想情况下,您应该将代码重写为
YsDbQuerySelect.Open;
while not YsDbQuerySelect.eof do begin
// making a file... code removed, not relevant
YsDbQuerySelect.Next;
end;
YsDbQuerySelect.Close;
原因是
if YsDbQuerySelect.RecordCount > 0 then begin
YsDbQuerySelect.First
应该是完全没有必要的,因为 a) 如果查询 return 的零条记录,YsDbQuerySelect.eof
将立即 return False 因此 while
循环将永远不会执行并且b) 如果查询 做 return 任何记录,FDQuery 的数据集游标将在第一条记录上,因此对 First
的调用是多余的。
在任何情况下,一般来说,使类似 TQuery 的数据集的行为依赖于其 RecordCount
变量是不好的做法,因为它可能不可靠且效率极低,因为它可能导致数据集检索所有匹配记录。
如果您绝对必须检查查询 return 的记录并向用户发送消息,如果没有,只需替换您的
if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
YsDbQuerySelect.First; // ********** Exception !
[etc]
来自
if not YsDbQuerySelect.Eof then begin
// your while not eof loop
end
else begin
MesInfo('No data to send');
end;
顺便说一句,我认为你不应该将你在自己的回答中描述的内容视为问题的解决方案,因为如果你得到的行为是由于 .DFM 文件损坏(我对此表示怀疑),它很可能再次发生。
下面是使用 Delphi Tokyo 编译时完美运行的非常简单的代码:
procedure TfData.DataSend(Memo : TMemo);
var SelectQuery : string;
begin
// Query simplified, more fields are retreived in original code, but same problem with simple query
SelectQuery := 'SELECT NUM as "NUM::TEXT" FROM TRACE WHERE DT_SENT is null ORDER BY DT_TRACE';
YsDbQuerySelect.SQL.Clear;
YsDbQuerySelect.SQL.Add(SelectQuery);
YsDbQuerySelect.Prepare;
try
YsDbQuerySelect.Open;
if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
YsDbQuerySelect.First; // ********** Exception !
while not YsDbQuerySelect.eof do begin
// making a file... code removed, not relevant
YsDbQuerySelect.Next;
end;
YsDbQuerySelect.Close;
end
else begin
YsDbQuerySelect.Close;
MesInfo('No data to send');
end;
except
on e : exception do begin
// Exception displays the annoying error
MesError(e.Message + ' SLQ : ' + SelectQuery);
end;
end;
end;
使用 Tokyo 10.3.2 编译时,同一真实 android 设备 (Zebra TC25) 上的相同简单代码 运行 不再有效。 "RecordCount" 方法 returns 6,然而,"First" 方法触发异常:类似于 "Cannot perform this operation on a closed dataset",原始消息是法语的:"Impossible d'effecteur cette opération sur un ensemble de données fermé"
我无法理解 "RecordCount" 如何在 "First" 触发此异常时 return 某些东西。而数据库中确实有6条记录。我也删除了然后重新创建了它们。同样的错误。 我尝试使用一些选项(获取选项等)但没有任何效果。这真的很烦人。
另请注意,其他操作可在同一个 SQLite 数据库上正常运行。该设备能够使用 TDFCommand 添加和删除记录,并使用 TDataSource 显示它们。只有 TDFQuery 遇到错误。
我删除了 TDFQuery 组件,然后删除了一个新组件。这有点奇怪,但它正在工作。我认为与 Delphi Rio 无关,但与损坏的文件有关?
理想情况下,您应该将代码重写为
YsDbQuerySelect.Open;
while not YsDbQuerySelect.eof do begin
// making a file... code removed, not relevant
YsDbQuerySelect.Next;
end;
YsDbQuerySelect.Close;
原因是
if YsDbQuerySelect.RecordCount > 0 then begin
YsDbQuerySelect.First
应该是完全没有必要的,因为 a) 如果查询 return 的零条记录,YsDbQuerySelect.eof
将立即 return False 因此 while
循环将永远不会执行并且b) 如果查询 做 return 任何记录,FDQuery 的数据集游标将在第一条记录上,因此对 First
的调用是多余的。
在任何情况下,一般来说,使类似 TQuery 的数据集的行为依赖于其 RecordCount
变量是不好的做法,因为它可能不可靠且效率极低,因为它可能导致数据集检索所有匹配记录。
如果您绝对必须检查查询 return 的记录并向用户发送消息,如果没有,只需替换您的
if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
YsDbQuerySelect.First; // ********** Exception !
[etc]
来自
if not YsDbQuerySelect.Eof then begin
// your while not eof loop
end
else begin
MesInfo('No data to send');
end;
顺便说一句,我认为你不应该将你在自己的回答中描述的内容视为问题的解决方案,因为如果你得到的行为是由于 .DFM 文件损坏(我对此表示怀疑),它很可能再次发生。