Delphi中ClientDataSet浅析

Delphi中ClientDataSet的用法小结 Delphi TClientDataSet控件中的ClientDataSet用法摘要继承自TDDataSet,其数据存储文件格式扩展名为Cds。它是一个基于文件数据存储和操作的控件。通过在Delphi中使用TClientDataSet控件,可以将应用程序与数据库驱动程序完全分离,并实现了传统数据集控件简单使用的特点,这为编写“精简”数据库应用程序提供了技术方法和手段。 阅读详情

Delphi中ClientDataSet浅析

 

       与一般的数据集组件不同,TClientDataSet使用的技术比较特别,本着高速度、低存储需求的原则TClientDataSet的内部使用了两个数据存储源。第一个是其Data属性,这是当前内存数据的视图,反映了所有的数据改变。如果用户从数据中删除一条记录,则此记录将从Data中消失,相应地,加入一条新记录后,此记录便存在Data属性中了。另一个数据源是Delta属性,故名思义,即增量的意思,这个属性反映了对数据的改变。无论是向 Data 属性新增还是删除记录,都会在Delta中记录下来,如果是修改了Data中的记录,则会在 Delta 保存两条相应的记录,一条是原始记录,另一条仅包含修改的字段值。

       正因为 Delta 的存在和 TClientDataSet 在内存中记录数据的特点,所有的改变都没有立即更新加对应的物理存储中,可以根据这些信息在适当的时候恢复,所以 TClientDataSet天生具有缓冲更新功能。为了使数据更新回数据存储源,我们要调用TClientDataSet中对应的方法。如果ClientDataSet 与 DataSetProvider关联,那么仅需调用TClientDataSet的ApplyUpdates方法即可保存数据的更新,但如果 TClientDataSet没有对应的TDataSetProvider存在,而是直接同文件关联,那么,这种方式是非常有趣的,我们在 BriefCase模型中会再次讲解这个问题。此时,如果使用TClientDataSet的 SaveToFile 和 LoadFromFile ,都会保留着Delta。调用MergeChangeLogClearChanges后,Delta的内容才会被清空。只是前者是将Delta的数据同Data结合起来,将改变存储到物理介质上,ClearChanges则是一股脑儿全部清空,将数据回复到原始状态。大部分的应用都是将TClientDataSet与TDataSetProvider结合使用的。两者联合使用的行为反映了Borland的设计宗旨,就是要提供一个面向分布式环境的思路。我们下面来慢慢解释。

       当我们将TClientDataSet对象的Active属性设为True或者调用其Open方法后,ClientDataSet 会向 DataSetProvider发送一个取数据包请求。于是DataSetProvider 便会打开对应的数据集,将记录指针指向第一条记录,然后从头到尾依次扫描。对于扫描到的每一条记录,都会将其编码成一个 variant 数组,我们通常将它称之为数据包。完成扫描后,DataSetProvider 会关闭指向的数据集,并将所有的这些数据包传递给ClientDataSet。在我提供的演示程序中,你可以清楚地看到这种行为(毕竟眼见为实吗!)。程序主界面右边的DBGrid连接到一个指向数据库表的数据源,DataSetProvider即指向此表。当选择了ClientDataSet | Load菜单项时,你可以看到表格的数据被依次扫描,一旦到达最后一条记录,表格便会被关闭,右边的DBGrid被清空,而左边反映ClientDataSet数据的DBGrid便出显示出内存中的数据来。由于这个过程会在DBGrid上反映出来,所以不到1000条记录的取出时间中,大部分都浪费在屏幕的更新显示上了,你可以选择ClientDataSet | View Table Loading来禁止显示,而达到加速的目的。

       在上面的描述中,我们没有提到一个重要的环节,即数据包是如何还原成表格的。那是因为 DataSetProvider 会将数据包中的元数据解码出来,根据元数据(我们可以理解为数据表的结构)便可以构造出与物理数据表一模一样的内存虚拟表。但要注意的是,尽管DataSetProvider指向的数据表可能有多个索引,但这些信息是不会放在数据包中的,换句话说,ClientDataSet当中的数据默认情况下是无索引的。但因为ClientDataSet具有与TDataSet一致的行为,所以我们可以在此基础上根据需要重建索引。

       在ClientDataSet中的数据被修改后,可以提交给物理数据表持久化这此改变。这个工作便是由DataSetProvider完成的。内部工作原理是:DataSetProvider创建一个TSQLResolver的实例,这个实例会生成要在底层数据上执行更改的SQL语句。详细地说,就是对修改日志中的每一条被删除、插入、更改记录生成对应的SQL语句。这个语句的生成也可以由用户控制,DataSetProvider的 UpdateMode 属性和ClientDataSet中的ProviderFlags属性都对SQL语句的生成有影响。当然,你也可以换一种方式,即采取同单机或C/S结构一样的数据直接操作机制,绕过SQL语句和缓冲更新机制来修改数据库。只需将 ResolveToDataSet属性设为True,那么DataSetProvider在持久化更新时便不会使用TSQLResolve,而是直接修改物理数据源。即定位到要删除的记录,调用删除语句,定位到修改记录,调用修改语句。我们可以对演示程序稍加修改,观察此种行为。请将演示程序中的 DataSetProvider的ResolveToDataSet属性由False改为True,运行。在界面中修改数据并且保存,你将会看到右边的导航按钮会在瞬间变得可用。

       更绝妙的是,Borland考虑到了应用的多样性,为我们提供了BeforeUpdateRecord事件,这样,当DataSetProvider对每个修改日志的记录进行操作时,都会触发此事件,我们可以在此事件中加入自己的处理,如“加密操作”、“商业敏感数据处理”等应用,从而极大地方便了程序员,让程序员对于数据具有完全的控制能力。分布式环境的复杂性对数据的存取提出了更高的要求,所以使用事务来保证数据的完整性和一致性是非常必要的,Borland考虑到了这一点,当调用ClientDataSet的 ApplyUpdates时,你可以传递一个整数值来指明可以容忍的错误数量。如果你的数据非常严格,则可以传递0值,这样,DataSetProvider在应用修改时便会打开一个事务,如果遇到错误,便会回退此事务,修改日志将保持原样,并且将出错的记录标记出来,最后会触发OnReconcileError事件。如果传递了一个大于0的数,则当出现的错误数量小于此指定值时,事务会被提交,发生错误而导致提交失败的记录会保留在Delta中,而提交成功的记录会从修改日志中删除。若错误数量达到指定值,则事务会回退,结果同整数值为0的情况。如果值为负数,则会交所以可提交的数据都提交,不可提交的数据仍然保存在修改日志中,并将出错记录标记出来。

 

http://hi.baidu.com/f4606304/blog/item/647184afcd372c1f4a36d612.html

Delphi Clientdataset处理关联出来的视图的问题 <br />在Delphi中常常用到ClientDataset来操作视图或者存储过程中关联出来的字段,但是在操作的时候会提示这些字段不能被修改,找了个函数 :<br />procedure   TLyffMainFrm.SetDstAllFieldCanEdit(dstNm:   TClientDataSet;   AddFields:   string='');<br />  var   tmpDst:   TClientDataSet;   <br />          I:   Integer;   阅读详情

相关推荐

Delphi无法修改Clientdataset的字段的解决方法

主题: 解决clientdataset 自定义字段无法在前台修改值的问题;数据库里面直接取的字段从前台可以修改,但是自定义的返回字段无法修改。 报错信息: error1:EDatabaseError with message ‘Field ‘选择’ cannot be modified 如果仅仅修改cdsA.field[0].ReadOnly=false,在Post的时候会报error2:...

踏雪寻梅 3659

delphi clientdataset.appenddata不能用于有聚合字段的数据集

delphi xe7, 有两个cds(cds1, cds2), cds1.commandtext='select a.id,sum(b.price*b.qty) from table1 left join table2 on a.orderno=b.orderno group by a.orderno cds1的查询语句中有sum函数,查出的数据值正确的。 cds2.appenddata(cds1.data,true); 但是如果复制给cds2,就不正确了。 比如cds1的记录sum值是825,

g58521547的专栏 575

delphi clientdataset 用法2

delphi clientdataset 用法 影响ClientDataSet处理速度的一个因素 TClientDataSet是Delphi开发数据库时一个非常好的控件。有很强大的功能。      我常常用ClientDataSet做MemoryDataSet来使用。还可以将ClientDataSet的数据保存为XML,这样就可以做简单的本地数据库使用。还有很多功能就不多说了。在使用Cl

流年~~ 6130

Delphi clientdataset的详细介绍

delphi Midas SQLServer的自增字段的处理1.新增时,表中有自增字段,但是不希望用Refresh,直接ApplyUpdates直接看见自增字段的值在DataSetProvider.AfterUpdateRecord写如下代码 DataSetProvider.Op

懒猫的专栏 6564

ClientDataSet数据更新,Delta解析,视图更新

将ClientDataset的Delta数据打包成JSon字符串 可以将这个JSon字符串传递到服务端, 进行解码,生成更新的SQL语句. 主键更新. 建议主键使用GUID,这样更新数度快, SELECT可以多个表,但是要更新的字段不要AS成其他名字. 打包的时候指定要更新的表和更新主键. 思路不错的.封装到位. 数字字段删除也可以更新.

Delphi FireDac Delta 记录操作日志 与 Delta转SQL

FDMemTable 记录操作日志 FDMemTable.Delta 转SQL语句

delphi中 clientdataset使用方法

1.基本情况介绍; clientdataset内存表,他的data属性存放的是数据, delta 增量记录的是日志, 就相当于数据库的 savepoint保存点;每当clientdataset的数据有变化时(onbeforeedit, onafteredit),savepoint都会变化。如果我们想取消一段时间的操作,我们可以先记录下这个savepoint,然后修改,如果想取消,直接让这个save

云中雁012345之成长 1万+

【Azure 架构师学习笔记】- Azure Databricks (1) - 环境搭建

Databricks 已经成为了数据科学的必备工具,今时今日你已经很难抛开它来谈大数据,它常用于做复杂的ETL中的T, 数据分析,数据挖掘等,特别适用于做数据建模,机器学习等。那么顺应时代,现在也来看看这个工具的内容。首先要有一个环境,基于Azure 的Databricks简称ADB。托管在Azure 上的Databricks已经被Azure进行了很大的优化, 在搭建时只需要简单的几步即可拥有一个环境,不过要提醒一句ADB的集群并不便宜,用完马上删掉或停止, 否则一晚过百美金就会烧掉。

MVP黄钊吉(發糞塗牆) 2298

Delphi 学习ClientDataSet

Delphi 学习ClientDataSet

xdAndSx的博客 1953

基因家族的鉴定-基于Windows系统上的HMMER

基因家族的鉴定-基于Windows系统上的HMMER。

liangjinghui123的博客 3249

R语言绘制森林图

运行上述代码后,将会生成一个标题为"森林图示例"的森林图。通过以上代码示例,你可以根据自己的数据集和需求创建定制的森林图。在实际应用中,你还可以进一步调整图形的样式,添加图例、坐标轴标签等,以使森林图更加美观和易于理解。在数据可视化领域,森林图是一种常用的图形类型,用于展示多个分类变量之间的关系。本文将介绍如何使用R语言创建森林图,并提供相应的源代码示例。森林图通常由垂直的线段表示不同类别的观测值,并且线段的长度表示数值变量的大小。上述代码中,我们为不同的类别分别指定了蓝色和红色作为颜色映射关系。

TechNovaX的博客 1045

delphi xe 之路(23)clientdataset的locate函数

locate主要用于查找数据,但是它的查找速度没有finding和going定位快。下面我举一个例子。 procedure TForm1.LocateBtnClick(Sender:  TObject); begin Start; if ClientDataSet1.Locate('Field1,Field2..',VarArrayOf['value1,value2..'], [])

5201314的专栏 2892

Keil uVision5 STM32 startup_stm32f10x_md_vl.s error A3906U Malformed via file target not created..

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 2778

delphi ClientDataSet

delphi Midas SQLServer的自增字段的处理 1.新增时,表中有自增字段,但是不希望用Refresh,直接ApplyUpdates直接看见自增字段的值 在DataSetProvider.AfterUpdateRecord写如下代码 DataSetProvider.Options.poPropogateChanges:=True; procedure TForm1.DataSetProvider1AfterUpdateRecord(Sender: TObject; SourceDS: TDa

173713873 1193

binning模式下和normal模式下相同曝光参数相同场景加权亮度差异消除方案优化(一)

摘要:针对ISP参数设置中浮点权重系数需转换为整数的问题,提出整数邻域搜索方案。该方法在浮点最优解附近(±1/±2)进行局部搜索,通过逐阶微调找到误差最小的整数权重组合,避免直接取整导致的误差反弹(误差从0.8%降至0.35%)。方案结合范围约束(1~15)和单调性约束(暗端递减、亮端递增),兼顾计算效率(单图耗时<10ms)与硬件兼容性,显著优于暴力搜索和简单取整,满足工程落地需求。

大熊 97

基于DINO自监督学习对YOLO11 Backbone进行预训练

这PoolHead将获取前一层的输出并应用卷积,然后应用自适应平均池化以将特征图的空间维度减小为固定且一致的大小(1x1)。这是必需的,因为否则空间维度会根据输入的大小而变化,这将使将 DINO 头部附加到主干变得困难,因为它需要固定的输入大小。在本指南中,我们将介绍如何使用 Lightly 使用 DINO 预训练 YOLO 11主干,以及如何将其重新加载到 Ultralytics 中进行微调。您可以使用不同的大小,例如,640这与 YOLO 中的默认图像大小更一致,但它也会在训练期间消耗更多 VRAM。

如果想成为中心,那么就到中心去吧。 1014

delphi中ClientDataSet的隐含功能

ClientDataSet组件支持很多特性,其中一些与三级结构有关,而且还可以用在其他环境中。该组件说明了一个数据库完全映象在内存中,这使得可以进行动态的操作,如建立一个索引,其他数据集合通常不支持该特性。例如,为了对查询分类,我们通常是重新执行它。为了索引一个局部表格,需要定义索引。只有ADO数据集合有一些与ClientDataSet一样的动态索引功能。索引并不是ClientDataS...

dgt93504的博客 152

matlab数学建模练习(2)练习电子科技大学数学实验

【代码】matlab数学建模练习(2)练习电子科技大学数学实验。

c_wrj_的博客 1435

Delphi中DataSource、ClientDataSet和主从关系(巢状数据)

一、DataSource的两个主要作用:1、连接数据集和数据感知控件2、连接两个存在数据关系的数据集(比如数据要一起联动,或者两个数据集本身就是主从关系)这时从数据集的DataSource要设置为指向主数据集的DataSource组件二、两个数据集设置主从方式(针对ADO控件,因为FireDAC的Dataset没有datasource属性)假设有两个表,teacher和stu...

1906

ZYNQ 网络通信的四种实现方案

一,ZYNQ MIO以RGMII 接口连接外部PHY芯片实现LWIP网络通信。 二,ZYNQ PS 的 ENET0/ENET1 通过 EMIO 的方式扩展至 PL,在 PL 中通过 RGMII 接口连接扩展子卡实现 LWIP 网络通信。 在PL中搭建了1个AXI 1G/2.5G Ethernet Subsystem以及1个AXI Direct Memory Access IP 核。这两个 IP核均通过AXI 总线经S_AXI_HP0 口与PS 连接,PS 通过AXI 总线对其进行配置和控..

wangjie36的博客 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Delphi中ClientDataSet的数据查找

Delphi中ClientDataSet的数据查找 博客分类:  Delphi   ClientDataSet的数据查找。 我所介绍的心得和技巧都是用ClientDataSet来做范例,也可以应用于其他的一些DataSet。废话就不多说了。我们还是先看代码,让后再总结。 1.Scanning 扫描数据查找 这是最简单最直接也是最慢的一种方法,遍历所有数据: pr

WaveYang的专栏 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: Delphi中ClientDataSet的用法小结
下一篇: Delphi中ClientDataSet的数据查找
WaveYang
博客等级 码龄22年 14粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值