I am having a problem resolving cache updates when delta includes fields that have a UNIQUE constraint in the database. I have a database with the following DDL schema (SQLite in memory can be used for playback):
create table FOO
(
ID integer primary key,
DESC char(2) UNIQUE
);
The source database table contains one record with identifier = 1 and DESC = R1
Recognizing this TFDQuery table (select * from FOO), if the following steps are followed, the generated delta will be correctly applied using ApplyUpdates:
- Update Record ID = 1 to DESC = R2
- Add new record ID = 2 with DESC = R1
Delta includes the following:
ApplyUpdates , delta . . 1 R2, , .
, , ( FDQuery.Delta), UNIQUE.
- ID = 2 DESC = TT
- = 1 DESC = R2
- 2 - TT DESC = R1
Delta :
, FireDAC , FDQUery Delta.
:
> VCL Forms; FDConnection FDQuery ; FDConnection SQLite ( ); , , - :
:
procedure TFrmMain.btnOkClick(Sender: TObject);
begin
// create the default database with a FOO table
con.Open();
con.ExecSQL('create table FOO' + '(ID integer primary key, DESC char(2) UNIQUE)');
// insert a default record
con.ExecSQL('insert into FOO values (1,''R1'')');
qry.CachedUpdates := true;
qry.Open('select * from FOO');
// update the first record to T2
qry.First();
qry.Edit();
qry.Fields[1].AsString := 'R2';
qry.Post();
// append the second record to T1
qry.Append();
qry.Fields[0].AsInteger := 2;
qry.Fields[1].AsString := 'R1';
qry.Post();
// apply will not generate a unique constraint violation
qry.ApplyUpdates();
end;
:
// create the default database with a FOO table
con.Open();
con.ExecSQL('create table FOO' + '(ID integer primary key, DESC char(2) UNIQUE)');
// insert a default record
con.ExecSQL('insert into FOO values (1,''R1'')');
qry.CachedUpdates := true;
qry.Open('select * from FOO');
// append a temporary record (TT)
qry.Append();
qry.Fields[0].AsInteger := 2;
qry.Fields[1].AsString := 'TT';
qry.Post();
// update R1 to R2
qry.First();
qry.Edit();
qry.Fields[1].AsString := 'R2';
qry.Post();
qry.Next();
// update TT to R1
qry.Edit();
qry.Fields[1].AsString := 'R1';
qry.Post();
// apply will generate a unique contraint violation
qry.ApplyUpdates();