DataSnap客户端修改CommandText执行插入报错的解决方法
DataSnap客户端执行INSERT报错的解决办法
问题根源
报错Remote error: commandtext changes are not allowed的原因很明确:你客户端的TClientDataSet绑定的是服务器端的TDataSetProvider,而这个Provider默认是为了同步服务器端TFDQuery的数据集设计的,不允许客户端直接修改CommandText来执行自定义SQL命令。
方案一:服务器端新增远程方法(推荐)
这是最安全规范的做法,把数据操作逻辑封装在服务器端,客户端仅调用预设方法:
- 在服务器的DataSnap模块(比如
TDSServerModule)中添加一个公开方法,专门处理插入操作:
procedure TServerModule1.DoInsertRecord(const AParamValue: string); begin // 调用服务器端的TFDQuery实例执行插入 FFDQuery1.Close; FFDQuery1.SQL.Text := 'INSERT INTO [table_name] (param) VALUES(:v)'; FFDQuery1.Params.ParamByName('v').AsString := AParamValue; FFDQuery1.ExecSQL; end;
- 将该方法注册为远程可调用:
procedure TServerModule1.DSServerModuleCreate(Sender: TObject); begin // 注册方法,允许所有客户端调用 DSServerClass1.RegisterMethod('DoInsertRecord', DoInsertRecord, rmAll); end;
- 客户端调用这个远程方法:
var ServerProxy: TServerModule1Client; begin // 通过已连接的DSProviderConnection创建代理对象 ServerProxy := TServerModule1Client.Create(DSProviderConnection1.DBXConnection); try ServerProxy.DoInsertRecord('a'); // 可选:刷新ClientDataSet获取最新数据 ClientDataSet2.Refresh; finally ServerProxy.Free; end; end;
方案二:允许客户端传递CommandText(不推荐)
如果非要在客户端直接编写SQL执行,需要修改服务器端配置:
- 找到服务器端的
TDataSetProvider,打开它的Options属性,勾选poAllowCommandText。 - 客户端执行前指定
CommandType:
ClientDataSet2.CommandType := ctCommandText; ClientDataSet2.CommandText := 'INSERT INTO [table_name] (param) VALUES(:v)'; ClientDataSet2.Params.ParamByName('v').AsString := 'a'; ClientDataSet2.Execute;
注意:这种方式风险极高,客户端可执行任意SQL命令,极易引发SQL注入问题,仅适合完全信任的内部封闭环境使用。
内容的提问来源于stack exchange,提问作者sh sh
相关产品推荐
相关产品推荐

