I have a DBXpress data structure connected to a Firebird database. I'm adding data pagination over a ClientDataSet, DataSetProvider and SQLQuery combination.
It was working well but recently it started to raise unknown isc error 0 exception
after calling Next many times.
The pagination code is:
if not ClientDataSet.Active then
ClientDataSet.Open;
RecNo := ClientDataSet.RecNo; // Keep track of selected record
ClientDataSet.DisableControls;
LastRecNo := GetLastRecNo;
if LastRecNo > -1 then
begin
ClientDataSet.RecNo := LastRecNo;
ClientDataSet.Next;
while (not ClientDataSet.Eof) and (Result < DATA_PAGE_SIZE) do
begin
...
ClientDataSet.Next; // The exception is raised here
Inc(Result);
end;
end;
ClientDataSet.RecNo := RecNo;
ClientDataSet.EnableControls;
The exception in intermittently raised, it could mean a connection issue, but the database is stored locally, the connection string is something like localhost:C:\Path\Base.FDB
.
EDIT: This code is fired when user scrolls down the mouse, move down the scroll bar or navigates to the items that are next to the end of the list. On recent tests I've discovered the exception is only raised if the code is executed normally. If there is a break-point, or if I put there some sleeps, it executes normally. I'm also sure I don't have any other thread changing the ClientDataSet.
I found out that I was using FetchOnDemand = True
and PacketRecords = 400
. It is probably a concurrency issue on TClientDataset itself or some low-level Delphi implementation of fetching records on demand.
The glitch is gone if you set FetchOnDemand = False
. I know it is not a solution if you have huge datasets, but that wasn't my case. I preferred to simply fetch the records at first and paginate over them already in-memory.