Delphi客户端数据集只读

3

我目前正在测试以下内容:

  1. 一个指向IB数据库的SQLConnection。
  2. 一个SQLDataset,其SQLConnection字段设置为上述SQLConnection。
  3. 一个DatasetProvider,其Dataset字段值为(2)中的SQLDataset。
  4. 一个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仅填充一条记录。然而,当我手动编辑该记录,点击提交(Post),然后尝试使用某种方法提交更改时,

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

它崩溃了,显示“SQLDataset1: Cannot modify a read-only dataset.”(SQLDataset1:无法修改只读数据集)。

我已经检查了提供程序和客户端数据集的ReadOnly属性,并且SQL没有连接查询。

这个错误是什么原因引起的呢?


你如何打开ClientDataSet?GetCurrEmployee方法只使用SQLDataSet。 - mjn
回应mjustin的问题,当DataSetProvider的Data属性被分配给ClientDataSet时,ClientDataSet将会处于活动状态(除了Data属性中包含的任何数据外,它还将具有元数据)。一个活动的ClientDataSet是打开的。 - Cary Jensen
2个回答

5

看起来你的ClientDataSet.Data属性是从DataSetProvider的Data属性中获取数据的。根据你描述的设置,你应该能够简单地调用ClientDataSet.Open,这将从DataSetProvider获取数据。

顺便提一下,当调用ClientDataSet.ApplyUpdates方法时,DataSetProvider的默认行为是向连接对象发送SQL查询,而不是从获取数据的DataSet发送(假设是同质查询)。确保你的DataSetProvider.ResolveToDataSet属性没有设置为true。

最后,与此无关的是,你上面的代码似乎容易受到SQL注入攻击(虽然我没有测试过)。更安全的方法是使用参数来定义WHERE子句。如果有人���Edit1中输入以下内容,你可能会遇到麻烦(假设InterBase使用了drop table语法):1;drop table employee;


+1 给出了一个很棒的答案,很高兴在这里见到你。很期待你能为 SO 做出贡献! - Argalatyr

0

检查 TIBDataSetLiveMode 属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接