最近维护一个项目,里面用到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. vue-cli3使用webpack-spritesmith配置雪碧图

    一.背景问题 项目中如果有大量的小图标,如果不使用阿里的iconfont.UI给一个加一个,加一个引用一个,每个图标虽然很小,但是也是一次请求,每次请求都是消耗性能资源的. 二.解决思路 使用webp ...

  2. Thymeleaf的一些操作

    1. js取值 <script th:inline="javascript"> var message = [[${message}]]; console.log(me ...

  3. Bootstrap常用单词组

    布局容器 .container 固定宽度 .container-fluid 全屏 .row 行 .col-lg- 大屏幕 .col-md- 中屏幕 变量 @grid-columns: 12 列数 @g ...

  4. linux编译链接找不到库文件的解决方法。

    今天编译出现ld: 0706-006 Cannot find or open library file: -l xerces-c_static,ld:open(): A file or directo ...

  5. BZOJ-1721|线性dp-缆车支柱

    Ski Lift 缆车支柱 Description Farmer Ron in Colorado is building a ski resort for his cows (though budge ...

  6. (转)AutoML for Data Augmentation

    AutoML for Data Augmentation 2019-04-01 09:26:19 This blog is copied from: https://blog.insightdatas ...

  7. Docker Swarm Mode 学习笔记 (基本概念)

    ​ Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具 节点 ​ 运行 Docker 的主机可以主动初始化一个 Swarm 集群 docker swarm ...

  8. dao层、service和action的运用和区别

    DAO层叫数据访问层,全称为data access object,属于一种比较底层,比较基础的操作,对于数据库的操作,具体到对于某个表的增删改查, 也就是说某个DAO一定是和数据库的某一张表一一对应的 ...

  9. matlab 入门

    ---恢复内容开始--- 1.cast表示将元素转化成对应的ASCII值 如cast('hellothere','uint8')输出结果为104 101 108 108 111 116 104 101 ...

  10. ZJOI2019游记

    Day-2 本蒟蒻有幸能去参加ZJOI2019,然而出发前就做好了爆0的准备. 坐了差不多6,7个小时的车,车上基本就是在颓知乎和打雀,然后就到了酒店. 招宝山酒店--本人住过的第一个四星级酒店,看上 ...