Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

dbExpress and Autoincrement Fields - how to insert a record 1

Status
Not open for further replies.

nurya

Technical User
Mar 2, 2004
12
0
0
ES
Hi everybody,

Recently I have moved from BDE and TBDEClientDataSet to dbExpress and TClientDataSet with a Provider (but in the same DataModule).
My application is server-client and needs to keep track of 'Events' and 'Activities' so I have two Log tables, which use a Key Field named 'Index' of type Autoincrement.

When I try to insert a record in any of these tables, the program raises an EDatabase Exception : Field 'Index' must have a value, in the 'Append' instruction.

If I remove the field 'Index' from the Fields Editor of the TClientDataSet (tbEventsLog), the exception is now EDBClient, with message 'Field value required'. If I keep the 'Index' field in the Fields Editor but changes the Read Only property to True, I also receive a 'Field value required' exception.

As I didn't have this problem in the previous version (with BDE and TBDEClientDataSet), I guess the problem has to do with dbExpress or TClientDataSet management of Autoincrement fields.

Can anybody give me an explanation and a solution to this problem?

Thanks!

Nurya

PS: Sorry for my English! ;-)
 
I'm not totally sure what is happening in your situation as TAutoincField inserts it own values. You could try this:

private
FLastLocalKey:integer;

function GetLocalKey:integer;
begin
Dec(FLastLocalKey);
Result:=FLastLocalKey;
end;

procedure ClientDataset1.OnNewRecord(Dataset:TDataset);
begin
with FieldbyName('Index')do
begin
ReadOnly:=false;
asInteger:=GetLocalKey;
end;
end;

The fun and games with autoinc fields usually comes when updating to the database.

Have fun
Simon
 

Thank you very much, VintageWine. But I'm afraid I should have given more detailed information:

I work with a Sybase Database, in which I have defined tbEventsLog and tbActivitiesLog. Both of them have several fields, and an 'Index' field (primary key). 'Index' properties are:

Data Type : Float
Value: System defined default value: AUTOINCREMENT

Therefore, the associated TClientDataSets in the Data Module, have an image of these tables. 'Index' is a TFloatField (fkData) and not a TAutoInc.

My code looks like this (TM2DMTableLog is a thread that inserts a record in the corresponding table of the database)

procedure TM2DMTableLog.InsertRecord;
begin
with FClientDataSet do begin
DisableControls;
try
Last;
Append; //Here the Exception is raised.
Edit;
FieldByName(Column1).AsInteger := FLogRecord.Column1;
..... // The same for all the columns
// except the 'Index' column, because
// has a default value determined by the
// database.
ApplyUpdates(-1);
finally
EnableControls;
end;
end;

This works fine with BDE and TBDEClientDataSet, but not now, with dbExpress and TClientDataSet with a Provider.
Any idea?

Thanks,

Nurya ;-)
 
Yes. Follow my previous suggestion. That generates a temporate Index value for use in your application until the save to database.

Delphi has not picked up from the database that it is an autoinc field. In fact it can't. Delphi doesn't handle the concept of float autoinc fields, only integer ones.

You will also need to stop Delphi updating the index field back to the database, as the database needs to generate the (real) new value. You can use field provider flags, do in the dbexpressdataset not the clientdataset.

Hope this makes sense
Simon
 

Thank you so much, Simon. I couldn't have done it without you.

Just one more note: as I have the poAllowCommandText in the Provider set to True, the ProviderFlags property must be set in the Index field of the TClientDataSet and not in the DataSet.
Nevertheless, I have it set in both ..... just in case, you know! ;-)

Once again, thank you very very much! I am in debt with you.

Nurya
 
Unless things have changed in D7 (I use D6) the provider flags in the TClientDataet are ignored. Its a pity, half, but only half, the code to implement them is in the VCL.

Presumably you do something like OnBeforeUpdate, if FindField('Index')<>nil then ProviderFlags=........
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top