繁体   English   中英

无法使用DataSnap客户端进行插入

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM