我目前正在测试:
我使用以下方法(从 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;
Run Code Online (Sandbox Code Playgroud)
它只用一条记录填充 DBGrid。但是,当我手动编辑记录时,单击发布,然后尝试提交更改,使用
MainDM.ClientDataset1.ApplyUpdates(0); // <<<<<<
Run Code Online (Sandbox Code Playgroud)
它会爆炸,并显示消息“SQLDataset1:无法修改只读数据集”。
我检查了 Provider 和 ClientDataset 的 ReadOnly 属性,并且 SQL 没有连接。
什么可能导致错误?
您的 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;