Если вы заполняете CDS с помощью оператора SELECT, вам не нужно выполнять упражнение по отправке специального оператора INSERT.
Вы должны иметь возможность просто позвонить
ClientDataSet3.Insert;
// populate fields here
ClientDataSet3.Post;
Затем следует вызов ClientDataSet3.ApplyUpdates.
Точно так же вы можете выполнить DELETE, просто вызвав ClientDataSet3.Delete.
Созданием необходимых операторов INSERT, DELETE и UPDATE занимается поставщик CDS. Однако я не утверждаю, что вы не можете выполнить INSERT так, как вы пытаетесь - он должен работать нормально.
Отсюда я не могу сказать, что не так с вашим INSERT, поэтому вместо этого вот некоторый код, который работает для меня (включая операторы CREATE TABLE и т. д.), чтобы вы, возможно, могли «увидеть разницу». Я использую XE6 на 64-разрядной версии Win7 и версию 3.8.5.0 sqlite3.dll от 4 июня 2014 года.
Пример кода предоставляет 3 способа (все проверенные и работающие) выполнения вставки: два с использованием пользовательских операторов INSERT и третий с использованием поведения вставки по умолчанию CDS, которое можно вызвать в коде (CDS1.Insert) и щелкнув значок ' +' на DBNavigator. Поведение вставки CDS по умолчанию требует специальной обработки: хотя столбец ID на сервере определен как Autoinc, получить значение autoinc при выполнении вставки CDS проблематично, поэтому в коде используется метод, описанный здесь:
http://edn.embarcadero.com/article/20847
создания временного отрицательного значения идентификатора, которое заменяется в процессе применения CDS ApplyUpdates. Обратите внимание, что в DFM указано, что мера, упомянутая в разделе "Ошибки" ссылки относительно ProviderFlags в поле идентификатора SqlQuery, необходима, поскольку значение столбца идентификатора на сервере представляет собой 64-разрядное целое число.
type
TDataOperation = (doCreateTable, doDropTable, doInsert, doInsertUsingParams, doSelect);
TForm3 = class(TForm)
[...]
{ private declarations }
ID : Int64;
function NextID : Int64;
[...]
end;
implementation
{$R *.dfm}
const
scCreateTable = 'CREATE TABLE [MATable2] ([ID] INTEGER NOT NULL '
+ #13#10 + 'PRIMARY KEY AUTOINCREMENT, [AName] VARCHAR(20), '
+ #13#10 + ' [AMemo] MEMO)';
scDropTable =
'DROP TABLE [MATable2]';
scInsert1 =
'INSERT INTO [MATable2] (AName, AMemo) VALUES(''a'', ''A memo'')';
scSelect =
'SELECT * FROM [MATable2]';
scInsertUsingParams =
'INSERT INTO [MATable2] (AName, AMemo) VALUES(:AName, :AMemo)';
procedure TForm3.PerformTableOperation(Operation : TDataOperation);
var
Param : TParam;
begin
if {(Operation in [toCreate, toDrop]) and} CDS1.Active then
CDS1.Close;
case Operation of
doCreateTable : begin
CDS1.CommandText := scCreateTable;
CDS1.Execute;
PerformTableOperation(doSelect);
end;
doDropTable : begin
CDS1.CommandText := scDropTable;
CDS1.Execute;
end;
doSelect : begin
CDS1.CommandText := scSelect;
CDS1.Open;
end;
doInsert : begin
CDS1.CommandText := scInsert1;
CDS1.Execute;
PerformTableOperation(doSelect);
end;
doInsertUsingParams : begin
CDS1.CommandText := scInsertUsingParams;
// CDS1.FetchParams;
CDS1.Params.ParamByName('AName').AsString:= 'bcdef';
CDS1.Params.ParamByName('AMemo').AsString := 'memo b';
CDS1.Execute;
CDS1.Params.Clear;
PerformTableOperation(doSelect);
end;
end;
if CDS1.Active then // it won't be after a toDrop
CDS1.ApplyUpdates(-1);
end;
procedure TForm3.OpenConnection;
begin
SqlConnection1.Open;
end;
procedure TForm3.btnCreateClick(Sender: TObject);
begin
PerformTableOperation(doCreateTable);
end;
[etc ...]
procedure TForm3.btnReopenClick(Sender: TObject);
begin
CDS1.Close;
PerformTableOperation(doSelect);
end;
procedure TForm3.btnSelectClick(Sender: TObject);
begin
PerformTableOperation(doSelect);
end;
procedure TForm3.CDS1AfterDelete(DataSet: TDataSet);
begin
CDS1.ApplyUpdates(-1);
end;
procedure TForm3.CDS1AfterPost(DataSet: TDataSet);
begin
CDS1.ApplyUpdates(-1);
end;
procedure TForm3.CDS1NewRecord(DataSet: TDataSet);
begin
CDS1.FieldByName('ID').AsInteger := NextID;
end;
function TForm3.NextID: Int64;
begin
Dec(ID);
Result := ID;
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
OpenConnection;
end;
end.
И вот частичный DFM, чтобы свести к минимуму необходимость угадывать, как настроены мои компоненты БД.
object Form3: TForm3
[...]
object DBGrid1: TDBGrid
Left = 8
Top = 8
Width = 456
Height = 193
DataSource = DataSource1
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
Columns = <
item
Expanded = False
FieldName = 'ID'
Visible = True
end
item
Expanded = False
FieldName = 'AName'
Visible = True
end
item
Expanded = False
FieldName = 'AMemo'
Visible = True
end>
end
[...]
object DBNavigator1: TDBNavigator
Left = 16
Top = 216
Width = 240
Height = 25
DataSource = DataSource1
TabOrder = 6
end
object DBMemo1: TDBMemo
Left = 207
Top = 259
Width = 185
Height = 74
DataField = 'AMemo'
DataSource = DataSource1
TabOrder = 7
end
object DBEdit1: TDBEdit
Left = 24
Top = 264
Width = 121
Height = 21
DataField = 'AName'
DataSource = DataSource1
TabOrder = 8
end
object SQLConnection1: TSQLConnection
ConnectionName = 'SQLITECONNECTION'
DriverName = 'Sqlite'
LoginPrompt = False
Params.Strings = (
'DriverName=Sqlite'
'Database=D:\delphi\xe6\sqlite\matestdb.sqlite')
Connected = True
Left = 40
Top = 16
end
object SQLQuery1: TSQLQuery
MaxBlobSize = 1
Params = <>
SQL.Strings = (
'select * from [matable2]')
SQLConnection = SQLConnection1
Left = 128
Top = 16
object SQLQuery1ID: TLargeintField
FieldName = 'ID'
ProviderFlags = [pfInWhere, pfInKey]
end
object SQLQuery1AName: TWideStringField
FieldName = 'AName'
end
object SQLQuery1AMemo: TWideMemoField
FieldName = 'AMemo'
BlobType = ftWideMemo
Size = 1
end
end
object DataSetProvider1: TDataSetProvider
DataSet = SQLQuery1
Options = [poAllowCommandText, poUseQuoteChar]
UpdateMode = upWhereKeyOnly
Left = 216
Top = 16
end
object CDS1: TClientDataSet
Aggregates = <>
CommandText = 'select * from MATable2'
Params = <>
ProviderName = 'DataSetProvider1'
BeforeInsert = CDS1BeforeInsert
AfterInsert = CDS1AfterInsert
BeforePost = CDS1BeforePost
AfterPost = CDS1AfterPost
AfterDelete = CDS1AfterDelete
OnNewRecord = CDS1NewRecord
AfterApplyUpdates = CDS1AfterApplyUpdates
Left = 288
Top = 16
object CDS1ID: TLargeintField
FieldName = 'ID'
end
object CDS1AName: TWideStringField
FieldName = 'AName'
end
object CDS1AMemo: TWideMemoField
FieldName = 'AMemo'
BlobType = ftWideMemo
Size = 1
end
end
object DataSource1: TDataSource
DataSet = CDS1
Left = 344
Top = 16
end
end
person
MartynA
schedule
21.07.2014