[英]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.