最近维护一个项目,里面用到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. psql 存储过程

    --添加人员和虹膜注册信息 CREATE OR REPLACE FUNCTION AddPersonInfoAndIrisEnrollInfo(personName character, workSn ...

  2. 安装redis报错 you need tcl 8.5 or newer in order to run redis test

    解决方法: wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz tar -zxvf tcl8.6.1-src.tar.gz -C ...

  3. 【js】关于this指针-理解call、apply、bind

    首次讲解视频,听了一下,录音声音太小(暂不知道该怎么调节),老是咳咳,不太流畅.暂时不理想,日后继续努力.(能写出来还不够,还要会说出来) 首先,this指针只存在于函数(function)中.用于指 ...

  4. hadoop(原生及CDH发行版)关键目录、配置文件及服务对应文件名详解

    四个最主要的配置文件(原生版本位于$HADOOP_HOME\etc\hadoop目录):mapred-site.xmlcore-site.xmlhdfs-site.xmlyarn-site.xml 在 ...

  5. BZOJ5279: [Usaco2018 Open]Disruption

    题目大意:给你一棵n个节点的树,这n条边称为原边,另给出m条带权值的额外边,求删去每条原边后通过给出的m额外条边变回一棵树的最小价值.题解:看完题面以为是Tarjan连通性之类的题目,冷静分析后想到是 ...

  6. 机器学习总结(一) Adaboost,GBDT和XGboost算法

    一: 提升方法概述 提升方法是一种常用的统计学习方法,其实就是将多个弱学习器提升(boost)为一个强学习器的算法.其工作机制是通过一个弱学习算法,从初始训练集中训练出一个弱学习器,再根据弱学习器的表 ...

  7. Privoxy教程

    简介 Privoxy 是一个 代理软件 简单说,就是进出你电脑的流量守门人.借由 Privoxy,我们可以控制出去的请求,还可以改写返回的响应.不必要的请求 – 比如视频广告的地址.图片广告的地址,我 ...

  8. 深入浅出ES6:不定参数和默认参数

    不定参数 我们通常使用可变参函数来构造API,可变参函数可接受任意数量的参数.例如,String.prototype.concat方法就可以接受任意数量的字符串参数.ES6提供了一种编写可变参函数的新 ...

  9. Nginx1.14.0+ModSecurity实现简单的WAF

    一.编译安装Nginx 1.安装依赖环境 $ yum -y install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel ...

  10. python-request-各方法使用及格式

    Request库方法介绍 方法 说明 requests.request() 构造一个请求,支撑一下各方法的基础方法  requests.get()  获取HTML网页的主要方法,对应于HTTP的GET ...