LocateRecord on a readonly Table fails in TZAbstractRODataset.SetFieldData:
if not RequestLive and (Field.FieldKind = fkData) then RaiseReadOnlyError;
Table State is dsSetKey.
how do you trigger that problem? LocateRecord is a part of TZAbstractRWDataSet.PSUpdateRecord. So it should only be called when updating data. If possible, please post a minimum working examplr that reproduces the problem.
Best regards,
Jan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i have written a MySQL replacement for BDE TTable.
The locate function for it requires LocateRecord in the same way as BDE:
function TBDEDataSet.Locate(const KeyFields: string;
const KeyValues: Variant; Options: TLocateOptions): Boolean;
begin
DoBeforeScroll;
Result := LocateRecord(KeyFields, KeyValues, Options, True);
if Result then
begin
Resync([rmExact, rmCenter]);
DoAfterScroll;
end;
end;
I have updated an old BDE project via text replace for .pas and .dfm
files: TTable -> TMySQLTable.
The locate function on the BDE version works with a readonly table. The
MySQL version fails in TZAbstractRODataset.SetFieldData.
sooo - I took a look at Delphi 7. LocateRecord is a protected method in TTable. It was not meant to be used. Unfortunately Borland decided to not document protected methods in the Delphi 7 help anymore. So I don't know the exact semantics of that method and I amnot going to install Delphi 6 just to take a look into that help ;)
Anyway - for debugging this I need a working example (Create script, insert script, program) that demonstrates the problem. Everything else is like trying to look into a crystal ball.
Best regards,
Jan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
my component is started in 2005 with Delphi 7. Therefore the old behaviour. In the zip is a short part of this component. The attributes for tzconnection are empty.
GetIndexField(0).AssignValue(Value) in my source causes the error.
My version of ZAbstractRODataset.pas is attached. I think, there is no risk.
I had to compile without your version of ZAbstractRODataset.pas because it seems to be from an aged version of Zeos. It simply doesn't fit anymore.
But then - for me the root cause is what you already posted here:
GetIndexField(0).AssignValue(Value) in my source causes the error.
It doesn't make sense to call AssignValue on a readonly dataset since AssignValue tries to modify the data.
On a deeper level: Why does LocateRecord - which I assume should locate a record - call SetKeyFields, which seems to be made to change the key field values? Does it make sense for a method that is meant to locate data to change data in reality?
Best regards,
Jan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello Hemmingway,
how do you trigger that problem? LocateRecord is a part of TZAbstractRWDataSet.PSUpdateRecord. So it should only be called when updating data. If possible, please post a minimum working examplr that reproduces the problem.
Best regards,
Jan
Hello Jan,
i have written a MySQL replacement for BDE TTable.
The locate function for it requires LocateRecord in the same way as BDE:
function TBDEDataSet.Locate(const KeyFields: string;
const KeyValues: Variant; Options: TLocateOptions): Boolean;
begin
DoBeforeScroll;
Result := LocateRecord(KeyFields, KeyValues, Options, True);
if Result then
begin
Resync([rmExact, rmCenter]);
DoAfterScroll;
end;
end;
I have updated an old BDE project via text replace for .pas and .dfm
files: TTable -> TMySQLTable.
The locate function on the BDE version works with a readonly table. The
MySQL version fails in TZAbstractRODataset.SetFieldData.
Best regards, Bernhard
Last edit: hemmingway 2021-11-16
Hello Bernhard,
sooo - I took a look at Delphi 7. LocateRecord is a protected method in TTable. It was not meant to be used. Unfortunately Borland decided to not document protected methods in the Delphi 7 help anymore. So I don't know the exact semantics of that method and I amnot going to install Delphi 6 just to take a look into that help ;)
Anyway - for debugging this I need a working example (Create script, insert script, program) that demonstrates the problem. Everything else is like trying to look into a crystal ball.
Best regards,
Jan
Hello Jan,
my component is started in 2005 with Delphi 7. Therefore the old behaviour. In the zip is a short part of this component. The attributes for tzconnection are empty.
GetIndexField(0).AssignValue(Value) in my source causes the error.
My version of ZAbstractRODataset.pas is attached. I think, there is no risk.
Best regards, Bernhard
Last edit: hemmingway 2021-11-18
Hello Bernhard,
I had to compile without your version of ZAbstractRODataset.pas because it seems to be from an aged version of Zeos. It simply doesn't fit anymore.
But then - for me the root cause is what you already posted here:
It doesn't make sense to call AssignValue on a readonly dataset since AssignValue tries to modify the data.
On a deeper level: Why does LocateRecord - which I assume should locate a record - call SetKeyFields, which seems to be made to change the key field values? Does it make sense for a method that is meant to locate data to change data in reality?
Best regards,
Jan
Hello Jan,
in BDE I found
procedure TTable.FindNearest(const KeyValues: array of const);
begin
CheckBrowseMode;
SetKeyFields(kiLookup, KeyValues);
GotoNearest;
end;
So I used SetKeyFields in my LocateRecord function in the same way.
Only the KeyFields are changed, not the real data.
Best regards, Bernhard