[英]Unable to do an insert using datasnap client
我正在尝试使用datasnap(以前从未使用过),并且遇到了一个奇怪的问题。 也许我做错了,我不知道。 我已经在窗体上放置了一个Clientdataset3。 将其链接到SQLConnection1(以相同的形式),该SQLConnection1连接到datasnap服务器。 我还已将Clientdataset3链接到服务器端的数据集提供程序(允许命令文本),该服务器已链接到要插入的表。 但是当我运行时:
procedure TForm3.AdvGlowButton1Click(Sender: TObject);
begin
clientdataset3.CommandText:='insert into "MY_TABLE" (twit) values (:A)';
clientdataset3.Params.ParamByName('A').AsString := cxmemo1.Lines.Text;
clientdataset3.Execute;
end;
我收到“远程错误:没有这样的表:插入”
我究竟做错了什么 ? 使用XE6,数据库是通过DBX的SQLite。
如果要使用SELECT语句填充CDS,则无需执行发送定制INSERT语句的工作。
你应该可以打电话
ClientDataSet3.Insert;
// populate fields here
ClientDataSet3.Post;
随后调用ClientDataSet3.ApplyUpdates。
同样,您可以仅通过调用ClientDataSet3.Delete来执行DELETE。
必要的INSERT,DELETE和UPDATE语句的构造由CDS的提供程序处理。 但是,我无意建议您不能以尝试的方式进行INSERT-应该可以正常工作。
我无法从这里告诉您INSERT出了什么问题,因此,这里有一些对我有用的代码(包括CREATE TABLE等语句),因此您可以“发现差异”。 我在日期为2014年6月4日的Win7 64位和v.3.8.5.0的sqlite3.dll上使用XE6。
范例程式码提供3种插入方式(所有方式都可检查和运作),两种使用自订INSERT陈述式,第三种使用CDS的预设插入行为,可以在程式码(CDS1.Insert)中按一下,然后按一下[ DBNavigator上的+'按钮。 默认的CDS插入行为需要特殊处理:尽管服务器上的ID列定义为Autoinc,但是在执行CDS插入时获取autoinc值是有问题的,因此代码使用此处描述的方法:
http://edn.embarcadero.com/article/20847
生成一个临时的负ID值,该值将在CDS ApplyUpdates过程中被替换。 从DFM请注意,由于服务器上的ID列值是64位Integer,因此有必要在链接的勘误部分中提及的关于SqlQuery ID字段中ProviderFlags的措施。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.