DBExpress tehnologija uopšte nije loša (naprotiv), samo što su ljudi ostavili neke stvari malo nedorađene. Jedna od tih stvari je i insert/updtate problem AutoInc Fielda, koje radi korektno samo kad je ciljni RDBMS Interbase/firebird. Više o tome ima na
Borland Developers Network , a ja obično rešavam problem na sledeći način.
1. Postavi se sledeći "niz" komponenti: TSQLDataSet (dbExpress paleta) -> TDataSetProvider (DataAcess paleta) -> TClietDataSet (DataAcess komponenta) -> DataSource.
2. Kao "Command Text" TSQLDataSeta se napiše text upita;
3. U "BeforeUpdateRecord" eventu TDataSetProvidera se upiše sledeći kod:
....
var i:integer;
nValue:variant;
tmpStr:string;
actiontype:integer;
Kveri: TSQLQuery;
SQLInsert, SQLUpdate, SQLDelete: String;
begin
Kveri:=TSQLQuery.Create(Self);
With Kveri do
begin
SQLConnection:=SQLConn;
case updatekind of
ukinsert:
begin
SQL.Clear;
SQL.Text:=SQLinsert;
actiontype:=0;
end; // insert
ukmodify:
begin
SQL.Clear;
SQL.Text:=SQLupdate;
actiontype:=0;
end; // update
ukdelete:
begin
SQL.Clear;
SQL.Text:=SQLdelete;
actiontype:=1;
end; // delete
end;
case actiontype of
0: begin
for i:=0 to deltads.FieldCount-1 do
begin
nvalue:=deltads.Fields
.NewValue;
tmpstr:=deltads.Fields.FieldName;
if (assigned(Params.FindParam(tmpstr))) then
begin
Params.ParamValues[tmpstr]:=deltads.Fields.Value;
if VarIsEmpty(nvalue) then
Params.ParamValues[tmpstr]:=deltads.Fields.OldValue
else
Params.ParamValues[tmpstr]:=nvalue;
end; // if
end; // for
end; //case 0
1: begin
for i:=0 to deltads.FieldCount-1 do
begin
tmpstr:=deltads.Fields.FieldName;
if (assigned(Params.FindParam(tmpstr))) then
Params.ParamValues[tmpstr]:=deltads.Fields.Value;
end;// for
end; //case 1
end; // case
ExecSQL(false);
applied:=True;
end; // with Kveri
Kveri.Free;
end;
SQLInsert, SQLUpdate & SQLDelete su upiti za operacije Ubacivanja, menjanja odnosno brisanja podataka iz odgovarajuće tabele, i njih morate definisati samui u slučaju da koristite ovaj pristup, jer DbExpress "ne ume" sam da generiše ove sql upite kad su autinc polja u pitanju.
Ova zavrzlama važi u slučaju da vam je autoinc polje iz baze podataka potrebno iz nekih razloga u vašoj aplikaciji. Ukoliko nije, postupak je mnogo lakši :)
Kao CommandText property TSQLDataseta navedete u select upitu sva polja iz tabele SEM AUTOINC polja (npr. umesto select * from Zaposleni, treba select Ime, Prezime,...... from Zaposleni, ukoliko recimo tabela Zaposleni ima AutoInc polje IDZaposlenog), i to je to. U tom slučaju nema potrebe za modifikacijom BeforeUpdateRecord eventa TDatasetProvider komponente.
BTW, ovih dana bih trebao da završim DBExpress - HOWTO (Čim prođe EXIT i sa gajbe mi se raziđe hipi komuna :)), tako da to mogu da postujem ovde ukoliko ima zainteresovanih.