【问题标题】:Datasnap - insert record with parameterDatasnap - 插入带参数的记录
【发布时间】:2014-08-11 10:40:36
【问题描述】:

在 DatasnapServer 我有: TSQLConnection 连接到我的数据库。 从我的表中获取数据的 SQLDataset1 (CommandType=ctQuery)(我们称之为“RESORTS”。 DataSetProvider1 连接到我的 SQLDataset1。 DataSetProvider1 设置为 AllowCommandText。

这工作正常。服务器启动没有问题。数据已获取。

在客户端我有: SQLConnection1 连接OK。Driver 是Datasnap。 DSProviderConnection1 链接到我的 SQLConnection1。 两者连接没有问题。 然后我有连接到 ClientDataSet1 的 DataSource1。 ClientDataSet1 连接到我的 DataSetProvider1。 将其设置为活动将从服务器检索数据。 全部显示在网格中。

在客户端表单上,我有一个 Edit1 和一个 Button1。 我尝试使用 ClientDataset1 运行查询

procedure TForm2.Button1Click(Sender: TObject);
begin
ClientDataSet1.Close;
ClientDataSet1.CommandText := ' INSERT INTO RESORTS (RES_NAME) VALUES (:RN)';
ClientDataSet1.FieldByName('RN').AsString := Edit1.Text;
ClientDataSet1.Execute;
ClientDataSet1.Open;
end;

我得到:ClientDataSet1:找不到字段“RN”。

所以,我想知道发生了什么?为什么我不能插入带参数的数据? 如果我将参数替换为: ClientDataSet1.CommandText := ' INSERT INTO RESORTS (RES_NAME) VALUES ("TRY")'; 我得到:远程错误:SQLDataSet1:游标未从查询返回。 但是,数据确实会被插入。

我在这里做错了什么?

【问题讨论】:

  • 在 'ClientDataSet' 的 'CommandText' 上按 F1 并读取,它正在尝试检索数据,因此 "Cursor not returned..".

标签: delphi datasnap


【解决方案1】:

(根据发布者在 cmets 中提供的新信息重写。)

你的整个方法都是错误的。 :-) 您不使用参数、SQL 或CommandTextTClientDataSet.CommandText documentation 明确表示:

CommandText 指定客户端数据集希望从其(内部或外部)提供程序接收哪些数据。它是:

  • 要执行的数据库服务器的 SQL 语句(查询)。
  • 表或存储过程的名称

一条 SQL 语句(查询)意味着只有 SELECT 是可接受的 SQL。 INSERT 不是查询,因此不能在 CommandText 中用于插入数据。

要在TClientDataSet中插入数据,只需InsertAppend,然后使用FieldByName设置值,然后调用Post方法:

ClientDataSet1.Insert;
ClientDataSet1.FieldByName('RES_NAME').AsString := Edit1.Text;
ClientDataSet1.Post;

要编辑,您只需使用Edit 而不是InsertAppend;其余部分保持不变。

ClientDataSet1.Edit;
ClientDataSet1.FieldByName('RES_NAME').AsString := Edit1.Text;
ClientDataSet1.Post;

当您准备好根据TClientDataSet 中所做的更改实际更新服务器数据时,将其称为ApplyUpdates

ClientDataSet1.ApplyUpdates(0);

【讨论】:

  • ClientDataSet1.Params.ParamByName('RN').AsString := Edit1.Text;给我“查询未返回光标”错误,数据被插入两次!
  • 它对我来说很好,但我不知道你在显示的代码完成后对打开的 ClientDataSet1 做了什么。您通常设置 SQL,分配参数值,执行查询,然后立即关闭它;执行 INSERT 语句后没有可访问的内容。 (如果您的代码引用 TSQLDataSet,则不是“Params.ParamByName”;正如我的代码所说,它只是 ParamByName。)等一下 - 我看到了问题。我刚刚复制了你的代码。将Execute 更改为ExecSQL。我将编辑我的答案。
  • 看来你必须先写'params'。否则: [dcc32 Error] Unit2.pas(131): E2003 Undeclared identifier: 'ParamByName'.ClientDataSet1 我用来获取网格中的数据,所以我必须先关闭它才能使用它执行查询。即使我删除了数据集的打开和关闭,我仍然会遇到同样的错误。
  • 如果你必须写Params.ParamByName,那么你就没有像你说的那样使用TSQLDataSet。无论如何,错误是因为您在执行 INSERT 后无法从查询中检索数据,因为没有。您需要再执行一次 SELECT 以使数据显示在网格中。
  • 没有。 TClientDataSet 根本不使用 SQL,除了可以在 CommandText 中提供的 SELECT。请参阅 TClientDataSet.CommandText 的帮助文件,它告诉您它只接受查询(这是一个 SELECT 语句)或表或存储过程的名称。当您的代码尝试使用 TClientDataSet 时,您不能使用 INSERT 语句。为 autoinc 字段分配一个值,让服务器处理更新它们。如果需要,您可以使用 TClientDataSet.OnReconcileError 事件来解决问题。
【解决方案2】:

您可以使用ClientDataSet1.ParamByName('RN').AsString := Edit1.Text;

【讨论】:

  • 不,你不能。 (我们已经完成了上述操作。)TClientDataSet 不允许在它的 CommandText 中插入 INSERT,因此没有参数可以分配给 ParamByName。正确的方法在我的回答中。
猜你喜欢
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
相关资源
最近更新 更多