我目前正在测试:


指向IB数据库的SQLConnection。
一个SQLDataset,其中的SQLConnection字段设置为上述字段。
具有(2)中的SQLDataset作为其Dataset字段值的DatasetProvider。
一个ClientDataset,其中ProviderName字段指向(3)中的提供者。


我使用以下方法(从Alister Christie借来的)获取数据...

function TForm1.GetCurrEmployee(const IEmployeeID: integer): OleVariant;
const
  SQLSELEMP = 'SELECT E.* FROM EMPLOYEE E WHERE E.EMPLOYEEID = %s';
begin
  MainDM.SQLDataset1.CommandText := Format(SQLSELEMP, [Edit1.Text]);
  Result := MainDM.DataSetProvider1.Data;
end;


仅用一条记录填充DBGrid。但是,当我手动编辑记录时,单击“发布”,然后尝试使用以下方式提交更改:

MainDM.ClientDataset1.ApplyUpdates(0); // <<<<<<


它用消息“ SQLDataset1:无法修改只读数据集”轰炸。

我已经检查了提供程序和ClientDataset的ReadOnly属性,并且SQL没有联接。

是什么导致错误?

最佳答案

看来您的ClientDataSet.Data属性是从DataSetProvider的Data属性填充的。使用您描述的设置,您应该能够简单地调用ClientDataSet.Open,它将从DataSetProvider获取数据。

顺便说一句,当调用ClientDataSet.ApplyUpdates方法时,DataSetProvider的默认行为是将SQL查询发送到连接对象,而不是从中获取数据的DataSet(假设是同质查询)。确保您的DataSetProvider.ResolveToDataSet属性未设置为true。

最后,不相关的注释是,您的上述代码似乎对SQL注入攻击开放(尽管我尚未对此进行测试)。使用参数定义WHERE子句更安全。如果有人在Edit1中输入以下内容,则可能会遇到麻烦(假设InterBase使用放置表语法):1;放置表员工;

10-05 22:43