On 24.11.2010 12:00, Hans-Inge Hansson wrote: > Still struggeling... > > I can get it to work with ONE primary key and first setting that > field, ReadOnly := false; BUT it's not my value entered. It seems to > be an autoincremented id. This will not work for me. I need support > for more than one primary key and I must be able to insert my own > (unique) values. This nuisance related to TClientDataSet and is not unique to DISQLite3. Problems arise because TClientDataSet does not automatically assigns unique values for ftAutoInc fields, which are used to represent the SQLite primary keys. This leads to duplicate primary keys when committing the changes. The solution is to assign unique negative values to ftAutoInc fields, which instruct TClientDataSet to NOT write those fields to the database when committing. The example project in DISQLite3\Demos\DISQLite3_ClientDataSet_Grid shows a simple way to to implement this solution. Below is a copy of the relevant code from DISQLite3_ClientDataSet_Grid_Form_Main.pas for your convenience. Alternatively, you can of course also store your own unique primary key after setting ReadOnly := False; but you must ensure that the key is indeed unique for the given database table. If your primary key spreads multiple fields, you will need to assign the TDISQLite3UniDirQuery.InitFieldDef event and change ftAutoInc fields back to more appropriate field types like ftInteger. This is unfortunately necessary because TClientDataSet only knows simple key fields and does not distinguish between auto-incrementing and non auto-incrementing keys as SQLite does. Example: procedure TfrmMain.DISqlite3UniDirQueryInitFieldDef( const AColumn: TDISQLite3Column; const AFieldDef: TFieldDef); begin case AFieldDef.DataType of ftAutoInc: AFieldDef.DataType := ftInteger; // Or any other type. end; end; As a result, you can now (pre-) assign your own primary key values in TClientDataSet. Ralf --- { When inserting new records, TClientDataSet does not fill in ftAutoInc fields automatically. This requires us to jump in and fill them with distinct values. Negative, decreasing numbers work well here since DISQLite3 uses positive PRIMARY KEYs only. Since TClientDataSet automatically sets ftAutoInc fields to ReadOnly, we must remove this protection before we can write the custom value. } procedure TfrmMain.ClientDataSet_NewRecord(DataSet: TDataSet); var f: TField; i: Integer; OldReadonly: Boolean; begin Dec(FID); for i := 0 to DataSet.Fields.Count - 1 do begin f := DataSet.Fields[i]; if f.DataType = ftAutoInc then begin DataSet.DisableControls; OldReadonly := f.ReadOnly; try f.ReadOnly := False; f.AsInteger := FID; finally f.ReadOnly := OldReadonly; // Restore previous ReadOnly value. DataSet.EnableControls; end; end; end; end; _______________________________________________ Delphi Inspiration mailing list yunqa@xxxxxxxxxxxxx //www.freelists.org/list/yunqa