Hi all,
after two days of debugging I'm sure to have found the source of some big
troubles we have with TTable and Oracle. I need to be a little bit more
specific, but as I believe this is a real, but very hidden bug, please
read on.
The problems show and are reproducable in a simple, codeless application
using TDbGrid, TDBNavigator, TDatasource and TTable. We have reproduced
the error with LookupCombos, too.
The visual effects are, that the grid simply shows the same rows of a
table several times.
The environment to reproduce this effects is a little bit special, but
after recognizing the error not that special.
We use Delphi C/S 3.02 (german) with BDE 4.51 (new dbclient.dll) under
NT4.0 SP3.
The problems show with our Oracle 7.3 NT workgroup server, not with
Access, which we use as low end database. This is understandable, if you
see below where the error is located.
Normally, we access Oracle with SQLLinks, but using the ODBC driver gives
the same problems.
The problem shows if the grid has more space to display rows than the
table actually has rows.
And only with TTable. TQuery works ok.
I think using TQuery with SQL is preferable over TTable, but TTable
should work and I like its simplicity.
After consulting DejaNews and several other bug solving resources without
luck, we decided to dig in ourselves.
This meant debugging the VCL, and I will reference to VCL source if
necessary.
To say it simple, the immediate cause to our problems was in
TDataLink.GetRecordCount.
This function gets the recordcount from its attached dataset reading
DataSource.DataSet.FRecordCount.
Knowing that a dataset has a property named RecordCount, I thought I had
a little "programmer too lazy" glitch (I know those) and happily changed
code into DataSource.DataSet.RecordCount.
This broke everything. After just hacking it to work, I could see that
using Recordcount instead of FRecordcount would solve the problem, but
raise lots of others.
To make it short, and get it off my chest. I think that Delphi is a
wonderful language and the VCL is quite a nice piece of work. But the
implementation of the TDataset.Recordcount completely differing from self
set standards and the internal use of FRecordcount made me nervous.
TBDEDataset.Recordcount gives the correct value. In our case 5. But due
to the error, the internal FRecordcount, which gets it value from many
places, had a value of 10. And this could be changed just by resizing the
grid.
Now, I traced the real cause of the bug in
TBDEDataSet.InternalGotoBookmark and there
DbiSetToBookmark, where I am stuck now.
Somewhere while filling internal buffers, the TDataset tries to read the
records prior to the ones it has in buffer with GetPriorRecords and
GetPriorRecord.
It uses its buffer[0] and the there stored bookmark to set the table to
this bookmark position with TDataSet.SetCurrentRecord(0).
Exactly this fails in our environment, leaving the dataset at EOF.
Reading prior records works, of course, up until BOF, resulting in the
visible results of duplicate rows.
The InternalGotoBookmark procedure is simple, and adding a BookmarkValid
call actually results in a bad bookmark. But handling this (with Check)
confuses the TDataset a lot.
MS Access bookmarks are valid, so the problem does not show. But who
knows.
We used another day to set up our Oracle again, with special regards to
sort orders and charactersets, but this only gave more Oracle experience,
but does not solve the problem :-)
Does anyone have a solution to this problem?
With best regards and thanks in advance.
---
Rdiger Hoppe
r...@edit.de