最近维护一个项目,里面用到ClientDataSet,由于之前接触ClientDataSet比较少,所以这个星期补了一下关于ClientDataSet的知识,并在此记录下我所了解到的并应用到实际项目中的ClientDataSet的知识。

项目新需求:1.从别的数据库导入物料资料,并允许操作员做修改后保存提交;2.从别的数据库导入价格资料,并允许操作员做出修改并保存;3.记录相应的日志。4.允许操作员过滤关键字查找。

(PS:项目的数据连接模式为:ADOConnection→ADOQuery→DataSetProvider→ClientDataSet→DataSource→数据集显示控件,包括DBGrid,DBLookupComboboxEh等)

更新单条记录

If cdsRecord.UpdateStatus <> usUnModified then  //让clientdataset处于非编辑状态
      Raise Exception.Create('You must apply updates before refreshing the current record.');
  cdsRecord.RefreshRecord;//更新单条记录,此处要注意,不单要在ClientDataSet中设置主键,要去对应的adoquery设置主键(ProviderFlags的pfInKey设置为true)

过滤

cdsRecord.Filtered := False;
  cdsRecord.Filter := 'itemcode='+QuotedStr(code);
  cdsRecord.Filtered := True;

如果过滤条件为空,则显示全部记录

cdsRecord.Filtered := False;
    cdsRecord.Filter :='itemcode like '+QuotedStr('%%');
    cdsRecord.Filtered := True;

过滤条件集添加“全部”记录

cdsLookUp.Close;
  cdsLookUp.CommandText := 'select * from jc_zd_item';
  cdsLookUp.Open;
  cdsLookUp.First;
  cdsLookUp.InsertRecord(['','全部','','QB']);

记录日志

在提交前的事件cdsRecordBeforeApplyUpdates中处理

procedure TForm1.cdsRecordBeforeApplyUpdates(Sender: TObject;
var OwnerData: OleVariant);
var
csdTemp: TClientDataSet;
i : Integer;
begin
//准备提交
if not (cdsRecord.ChangeCount>) then //判断数据集是否有更改,ChangeCount>0表示有更改
Exit;
csdTemp := TClientDataSet.Create(nil);
csdTemp.Data := cdsRecord.Data;//复制数据集,否则在这个事件里面处理自身的数据集会进入死循环
csdTemp.First; if not adqLog.Active then //adqLog是连接日志表的ADOQuery,属性LockType选择ltBatchOptimistic(批量提交),这就可以在提交前记录好日志,在提交后再把日志批量上传
adqLog.Active := True;
for i:= to csdTemp.RecordCount- do //whilt not csdTemp.eof do同理
begin
if csdTemp.UpdateStatus=usModified then //如果当前记录是修改的
begin
adqLog.Append;
adqLog.FieldByName('pk').AsString := 'itemcode';
adqLog.FieldByName('newValue').AsString := csdTemp.FieldByName('itemcode').AsString;
adqLog.FieldByName('remark').AsString := '修改';
adqLog.FieldByName('oldvalue').AsString := csdTemp.FieldByName('itemcode').OldValue;
adqLog.Post;
ShowMessage(IntToStr(Integer(csdTemp.UpdateStatus)));
end;
if csdTemp.UpdateStatus=usInserted then //如果当前记录是新增的
begin
adqLog.Append;
adqLog.FieldByName('pk').AsString := 'itemcode';
adqLog.FieldByName('newValue').AsString := csdTemp.FieldByName('itemcode').AsString;
adqLog.FieldByName('remark').AsString := '新增';
adqLog.FieldByName('oldvalue').AsString := '';
adqLog.Post;
end;
csdTemp.Next;
end;
end;

批量提交修改后的clientdataset数据集

if cdsRecord.State in [dsEdit, dsInsert] then //判断数据集是否在编辑状态,如果是,则把正在编辑的内容提交到内存
    cdsRecord.Post;
  cdsRecord.ApplyUpdates(0); //提交cdsRecord数据集到数据库,参数0表示遇到提交异常则返回,如果你能容忍某一条记录提交失败仍然可以执行下一条的,那么可以填写你的容忍值

这里要注意,DataSetProvider的UpdateMode要设置为upWhereKeyOnly,并在cdsRecord的主键(或其他不被修改的字段)的ProviderFlags的pfInKey设置为true。

在cdsRecordAfterApplyUpdates中提交日志

//提交后记录提交日志
if adqLog.State in [ dsEdit, dsInsert] then
adqLog.Post;
adqLog.UpdateBatch(arAll);//这里是ADOQuery的一个批量上传选项

ClientDataSet增加一条记录

cdsRecord.AppendRecord(['','',false,false,'2018-06-28 19:19:26','','','PM','']);

如果需要在ClientDataSet中处理SQL或生成字段信息,那么可以在ClientDataSet的CommandText处理,但前提是要在DataSetProvider的Options中设置poAllowCommandText为true。

待续......

ClientDataSet应用的更多相关文章

  1. delphi中的ClientDataSet组件的open和Execute方法各自在什么情况下用?

    ClientDataSet组件本来是给midas用的,也是所谓的borland的三层数据技术,使用这个控件必须发行midas.dll挺麻烦的 open是通过应用的SQL语句为SELECTexecute ...

  2. 捕获ClientDataSet.ApplyUpdates和SocketConnection异常

    核心提示:如何捕获ClientDataSet.ApplyUpdates的错误,不用ReconcileError... var cdsEmp:TClientDataSet; //保存 procedure ...

  3. clientdataset<---->json

    现在,DATASNAP倾向于使用JSON作为统一的数据序列格式,以期达到跨平台的效果.于是使用JSON便成为热点. unit uJSONDB;   interface uses SysUtils, C ...

  4. ClientDataSet使用locate或Filter定位到字段为空值的记录

    场景,程序想检查是否存在某个字段的值是空的,如果存在,则不允许增加记录,否则允许增加记录. 解决这个问题,我一开始用了两种错误的方法 if not clientdataset.locate('AFie ...

  5. Delphi ClientDataSet 主从结构 BUG

    使用ADO控件 .ClientDataSet .增加了从表与主表的关连字段 SheetID,别的设置全为默认.如图1所示 图1 ======= 问题 BUG: 打开主表与从表,先不对主表进行任何操作. ...

  6. ClientDataSet

    TField对象的SetText和GetText事件处理函数 使用TField对象的SetText和GetText事件处理函数可方便的解决字段的代码与代码所对应值的显示问题 TSimpleDatase ...

  7. DataSnap ClientdataSet 三层中主从表的操作

    非原创  摘自:http://hi.baidu.com/yagzh2000/blog/item/fc69df2cb9845de78b139946.html三层中主从表的操作(删除.新增.修改)一定要在 ...

  8. clientdataset.open 报错 Name not unique in this context

    clientdataset.open 报错  Name not unique in this context clientdataset有一些自定义字段,clientdataset绑定了adoquer ...

  9. ClientDataSet 心得

    1.   与TTable.TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端.很多数据库应用程序都用了BDE,BDE往往给发布带来很大的不便 ...

随机推荐

  1. java消息服务学习之JMS高级特性

    将介绍的内容是: 控制消息确认.为发送消息指定选项.创建临时目的地.使用JMS本地事务.异步发送消息 五个方面. 1.控制消息确认 在JMS消息得到确认之前,并不认为它已经成功使用.要成功使用消息,通 ...

  2. vue 路由守卫

    router.beforeEach((to, from, next) => { const nextRoute = [ 'login']; var token = window.localSto ...

  3. Hi3516A开发--接触(转)

    Hi3516A开发--接触

  4. Prometheus监控学习笔记之Prometheus的Relabel,SD以及Federation功能

    0x00 k8s 的监控设计 k8s 默认以及推荐的监控体系是它自己的一套东西:Heapster + cAdvisor + Influxdb + Grafana,具体可以看 这里 . 包括 k8s 自 ...

  5. day 06

    深浅拷贝 # 值拷贝:应用场景最多ls = [1, 'abc', [10]]​ls1 = ls  # ls1直接将ls中存放的地址拿过来# ls内部的值发生任何变化,ls1都会随之变化​ls2 = l ...

  6. 提升node.js中使用redis的性能

    问题初现 某基于node.js开发的业务系统向外提供了一个dubbo服务,提供向第三方缓存查询.设置多项业务数据并聚合操作结果.在QPS达到800时(两台虚拟机,每台机器4Core8G4node进程) ...

  7. objectarx 读取外部DWG图到当前图形

    void CTrimeDraw::MyReadDwgFile(CString str){ AcDbDatabase pExternalDb(Adesk::kFalse); // 外部图形数据库 if ...

  8. pam密码策略

    PAM 的使用历史 PAM 是关注如何为服务验证用户的 API.在使用 PAM 之前,诸如 login(和 rlogin.telnet.rsh)之类的应用程序在 /etc/passwd 中查找用户名, ...

  9. python链接mysql获得某列最大值

    import pymysqlconn = pymysql.connect(host='10.1.2.198', port= 3306 ,user='root',passwd='123456',db=' ...

  10. 初学者易上手的SSH-spring 01控制反转(IOC)

    这章开始学习SSH中最后的一个框架spring.Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用. 首先就来学习一下I ...