Delphi 多层数据库无状态模式下 ClientDataSet 分段读取服务器端记录的方法

Delphi中ClientDataSet的用法小结 Delphi TClientDataSet控件中的ClientDataSet用法摘要继承自TDDataSet,其数据存储文件格式扩展名为Cds。它是一个基于文件数据存储和操作的控件。通过在Delphi中使用TClientDataSet控件,可以将应用程序与数据库驱动程序完全分离,并实现了传统数据集控件简单使用的特点,这为编写“精简”数据库应用程序提供了技术方法和手段。 阅读详情
unit UDataModule3;
{------------------------------------------------------------------------------
  ClientDataSet 分段获取数据。有状态模式下,服务器端 select 出来100条,如果设置 ClientDataSet.PacketRecords := 10,
  则 ClientDataSet 一次获取10条,ClientDataSet.GetNextPacket 获取后继 10 条。服务器端缓存住 1000 条,并帮客户端维护游标。 
  在无状态模式下,服务器端不帮客户端维护游标。而且,如果记录太多,不应该让服务器端一次取出 1000 条并缓存在服务器内存里面。

  所以,这种情况下,服务器端应该是 Select first 10 * from MyTable

  然后,客户端每次需要读取后面的数据时,就执行 ClientDataSet.GetNextPacket; 方法来向服务器请求下一段数据。
  但是,这里的问题是:第一次读取数据,服务器里面只有10条,所有10条都已经读回客户端,
  则 ClientDataSet.GetNextPacket 时不会有向服务器读取数据的动作。查其代码,里面会判断一下 ProviderEOF 属性。

  所以,这里如果服务器端没有缓冲比10条更多的数据,则必须要重新设置 ProviderEOF 属性为 False 才能让它执行 GetNextPacket。
  但是,ProviderEOF 属性是 Protected 的,在程序里无法访问。

  So, 这里必须 Hack 一下 TClientDataSet。做法是这样的:

  Type

  TMyClientDataSet = class(TClientDataSet)
  public
    property ProviderEOF;
  end;

  通过继承,把 ProviderEOF 属性公开。

  然后,在 ClientDataSet2 需要设置 ProviderEOF 属性的地方,就可以这样:
  TMyClientDataSet(ClientDataSet2).ProviderEOF := False;

  然后,再执行 ClientDataSet2.GetNextPacket; 它就会去向服务器请求下一段数据了。

  然后,服务器怎么知道从哪里开始读取下一段数据?

  在 ClientDataSet2.BeforeGetRecords 事件里面,将 OwnerData 设置为当前记录排序字段的最大值;
  在服务器端的 DataSetProvider2.BeforeGetRecords 里面,为服务器端的 TQuery 的 select 参数赋值为 OwnerData。

  这个程序的例子,排序字段就是主键字段,是一个整数编号字段。

  很多时候,排序字段可以是时间字段。

  以下代码测试通过。

  pcplayer 2016-6-23

------------------------------------------------------------------------------}
interface

uses
  System.SysUtils, System.Classes, FireDAC.UI.Intf, FireDAC.VCLUI.Wait,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.Phys.Intf,
  FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys,
  FireDAC.Phys.FB, FireDAC.Phys.FBDef, FireDAC.Stan.Param, FireDAC.DatS,
  FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.Client, FireDAC.Comp.DataSet,
  Data.DB, Datasnap.DBClient, Datasnap.Provider, FireDAC.Comp.UI;

type
  TDataModule3 = class(TDataModule)
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    FDConnection1: TFDConnection;
    FDManager1: TFDManager;
    FDTransaction1: TFDTransaction;
    DataSetProvider1: TDataSetProvider;
    ClientDataSet1: TClientDataSet;
    ClientDataSet1XUHAO: TIntegerField;
    ClientDataSet1ID: TWideStringField;
    ClientDataSet1FULLNAME: TWideStringField;
    ClientDataSet1EMAIL: TWideStringField;
    DataSource1: TDataSource;
    FDQuery1: TFDQuery;
    FDStoredProc1: TFDStoredProc;
    FDQuery2: TFDQuery;
    DataSetProvider2: TDataSetProvider;
    ClientDataSet2: TClientDataSet;
    DataSource2: TDataSource;
    CldTemp: TClientDataSet;
    procedure DataSetProvider2BeforeGetRecords(Sender: TObject;
      var OwnerData: OleVariant);
    procedure ClientDataSet2BeforeGetRecords(Sender: TObject;
      var OwnerData: OleVariant);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure OpenClientDataSet2;
  end;

  //Hack 一下 TClientDataSet 以便这里能访问到其 ProviderEOF 属性。
  TMyClientDataSet = class(TClientDataSet)
  public
    property ProviderEOF;
  end;

var
  DataModule3: TDataModule3;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

{ TDataModule3 }

{-------------------------------------------------------------------------------
  这里的 FDQuery2 的 SQL 是:select first 10 * from MyTable

  这个 MyTable 里面的第一个主键字段是一个整数字段,叫做 XuHao

  这里的 ClientDataSet2.PacketRecords 是默认的 -1。因为这是无状态模式。
-------------------------------------------------------------------------------}

procedure TDataModule3.ClientDataSet2BeforeGetRecords(Sender: TObject;
  var OwnerData: OleVariant);
begin
  OwnerData := ClientDataSet2.Params[0].Value;  //将当前排序最大字段值传递给服务器。
end;

procedure TDataModule3.DataSetProvider2BeforeGetRecords(Sender: TObject;
  var OwnerData: OleVariant);
begin
  FDQuery2.Params[0].Value := OwnerData;  //给 服务器端的 select 参数赋值。
end;

procedure TDataModule3.OpenClientDataSet2;
begin
  with ClientDataSet2 do
  begin
    if not Active then
    begin
      Params[0].Value := 0;
      Open;
      Exit;
    end;

    CldTemp.CloneCursor(ClientDataSet2, True);
    CldTemp.Last;
    Params[0].Value := CldTemp.FieldByName('XuHao').AsInteger;


    TMyClientDataSet(ClientDataSet2).ProviderEOF := False;  //设置 ProviderEOF 为 False,后面的 GetNexPacket 才会被执行。
    ClientDataSet2.GetNextPacket;
  end;
end;

end.


----------------

又及:除了分段读取数据,这个方法还可以用于 ClientDataSet 已经根据某个服务器端的参数获取了一组数据,然后更换参数获取新数据,但原有数据不丢的情况。

通常做法是 Close; Params[0].Value := 'New param'; Open;但这样一来,原有数据在 ClientDataSet 中丢失了。现在可以不用做 Close 而是 GetNextPacket 的方式来获取新的参数的数据。测试通过。



c语言学习 GPS数据处理 题目内容: NMEA-0183协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The National Marine Electronics Associa-tion)制定的一套通讯协议。GPS接收机根据NMEA-0183协议的标准规范,将位置、速度等信息通过串口传送到PC机、PDA等设备。 NMEA-0183协议是GPS接收机应当遵守的标准协议,也是目前GPS接收机上使用最广泛的协议,大多数常见的GPS接收 阅读详情

相关推荐

delphi实现数据库连接池

delphi 实现数据库连接池,可以初始化连接池中数据库连接个数,动态创建新连接,及多线程互斥获取资源。

Delphi 中 FireDAC 数据库连接(多线程)

如果满足以下条件,FireDAC是线程安全的。一个连接对象和所有与之相关的对象(如TFDQuery、TFDTransaction等)在每个时刻都由一个线程使用。FDManager在线程开始之前被激活,通过设置FDManager.Active为True。这意味着,在一个线程打开一个查询后,直到它的处理完成,应用程序不能在另一个线程中使用这个查询和连接对象。同样,在一个线程启动一个交易后,直到交易完成,应用程序不能在另一个线程中使用这个交易和连接对象。

sensor_WU 博客 2824

压电传感器信号放大难题?用运放设计电荷放大器的5个关键步骤

本文详细解析了压电传感器信号放大难题,并提供了用运放设计电荷放大器的5个关键步骤。从电压放大到电荷放大的范式转换,到运放选型、反馈网络设计、PCB布局及频响特性验证,帮助工程师解决工业自动化中的信号衰减问题,提升测量精度和稳定性。

weixin_27303545的博客 447

Delphi 10 FireDac 连接池设置

使用FireDac 连接  MySQL数据库,参考官方帮助文档 http://docwiki.embarcadero.com/RADStudio/XE7/en/Multithreading_(FireDAC), 实现过程如下: 1、在DataModule界面上 放置一个  FDManager 控件; 2、在 Create 事件中: procedure TDM.DataModuleC

jhzhao的专栏 6822

C# 读取图片和扫描PDF中的文本

本博客将探讨如何使用C#和OCR库实现从图片和扫描的 PDF 中提取文本。Spire.OCR for .NET 是一个OCR文字识别库,专为在 .NET 应用程序中识别图片的文本而设计。首先,使用 Spire.PDF 将扫描的 PDF 转换为图片,然后利用 Spire.OCR 从这些图片中提取文本。由于该OCR库并不支持直接处理PDF,因此要从扫描的 PDF 中提取文本,我们首先需要将 PDF 文档转换为图片。转换完成后,再利用 Spire.OCR 从生成的图片中提取文本。方法来识别图片中的文本。

nuclear2011的博客 5401

IDM更改下载路径的详细指南

Internet Download Manager(IDM)是一款功能全面的下载加速工具,它支持多种浏览器和协议,能够显著提升下载速度,同时提供断点续传、多线程下载等实用功能。IDM的用户界面简洁明了,操作便捷,使得用户能够轻松管理下载任务。此外,IDM还支持自动分类下载文件、定时下载等高级功能,进一步提升了用户的下载体验。通过本文的介绍,相信用户已经掌握了如何在IDM中更改下载路径的方法。这一功能不仅提升了下载效率和文件管理便捷性,还满足了用户的个性化需求。

nntxthml的博客 1762

Delphi 学习ClientDataSet

Delphi 学习ClientDataSet

xdAndSx的博客 1950

【没有网络,安装python包】如何从 PyPI 下载并安装 Plotly 的离线包

在某些情况下,您可能需要在没有互联网连接的环境中安装 Python 包,例如在飞机上、在某些受限制的网络环境中或在需要离线安装的场景下。以下是如何在 PyPI(Python Package Index)下载 Plotly 包并进行离线安装的详细步骤。

赖德发的博客 1103

Delphi WebService Soap 一次提交多个 ClientDataSet 的简单方法

用 Delphi 做的 WebService 程序,服务器端有一个 SoapDataModule,里面是连接数据库的 DataSet 和 DataSetProvider,客户端的 ClientDataSet.ProviderName 对应的就是服务器端的 DataSetProvider. 简单的情况下,客户端提交对数据的修改,使用 ClientDataSet1.ApplyUpdates(0); 的代码就可以提交。 但是,如果有多个表需要提交,而且多个表需要在一个数据库事务里面提交,也就是其中一个表提交不

pcplayer的博客 882

SAP在sap我定义了三个帐套 T9 SGD,I9 CNY, C9 CMY 想使用三个不同的币种,那么 我在定义和激活非主分类账时 如何定义各自的币种 ?

摘要:在SAP中为非主分类账(T9、I9、C9)配置不同币种(SGD、CNY、MYR),需通过三个步骤实现:1)在FINSC_LEDGER中定义分类账货币类型;2)在OB22中为公司代码0919配置平行货币;3)在"定义和激活非主分类账"中关联币种。关键注意事项包括维护自定义货币类型(以Y/Z开头)、设置OB08汇率以及独立汇率评估。完成后可通过FB50测试凭证和FAGLL03验证各账套的币种金额显示。

金牌架构师 1011

Rerender A Video 技术浅析(四):跨帧约束

时间一致性是指在视频处理过程中,保持相邻帧之间内容、风格和运动的平滑过渡,避免出现视觉上的不连续性或伪影。时间一致性跨帧约束模块的主要目标是在视频增强、风格迁移等任务中,确保处理后的视频在时间维度上保持一致性和稳定性。该模块主要通过以下几种方式实现时间一致性:1.时序损失(Temporal Loss):最小化相邻帧之间的差异,确保帧间内容的平滑过渡。2.循环一致性损失(Cycle Consistency Loss):确保帧间转换的一致性,避免出现风格漂移。3.

m0_75253143的博客 1480

C\S结构中成批保存CLIENTDATASET中的数据

    转自:http://www.west263.com/info/html/chengxusheji/delphi/20080411/65524.html   这应该不算是什么技巧,估计有数据库方面程序的DELPHI程序员都知道;本来没有写想到需要把它写成一篇贴子,但前不久看个别刚入门的兄弟的代码时。才发展他们还在刀耕火种,为此才想把它写出来算是对入门的兄弟们的一点帮助,让大侠们见笑了...

注重长远 天天积累 cqujsjcyj 200

一般无穷积分的收敛判别法

文章目录积分里的狄屎判别法证明阿贝尔判别法总结补充:级数中的狄屎和Abel 积分里的狄屎判别法 F(u)=∫auf(x)dx在[a,+∞)F(u)=\int_a^uf(x)dx在[a,+\infty)F(u)=∫au​f(x)dx在[a,+∞)有界 x→+∞时,g(x)单减→0x\to+\infty时,g(x)单减\rightarrow0x→+∞时,g(x)单减→0 ⇒\Rightarrow⇒ ...

universe_1207的博客 1万+

ClientDataSet提升处理数据速度、减少内存消耗方法

将clientdataset的LogChanges属性设置为false,当LogChange是false时clientdataset不记录修改日志,这样可以提升处理数据速度、减少内存消耗。 注意:本方法不适用于ClientDataSet要进行保存操作

小祝的专栏 1601

大华 DSS 数字监控系统 itcBulletin SQL 注入漏洞复现

大华 DSs 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。大华 DSS存在SQL注入漏洞,攻击者 pota/services/itcBuletin 路由发送特殊构造的数据包,利用报错注入获取数据库敏感信息。攻击者除了可以利用 SQL注入漏词获取数据库中的信息例如,管理员后台密码、站点的用户人人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限poc验证是否存在漏洞如果你想查询用户名和密码。

holyxp的博客 4002

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Delphi TClientDataSet的使用技巧

1. TClientDataSet、TDataSetProvider的使用技巧 ClientDataSet是一个功能强大的类,通过在内存中模拟表格,实现了其它数据集组件所不具备的强大功能。 TClientDataSet从类的继承关系上来看,是TDataSet这个抽象类的子类,所以我们可以在TDataSet这个抽象层次上对其进行我们熟悉的操作,比如导航、排序、过滤、编辑。要注意的是,TCli

chinmusam的专栏 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Delphi 中 FireDAC 数据库连接(定义连接)

连接定义是一组参数,它定义了如何使用特定的FireDAC驱动将一个应用程序连接到DBMS。它相当于一个BDE别名、ADO UDL(存储的OLEDB连接字符串)或ODBC数据源名称(DSN)。关于支持的数据库管理系统和相应的参数列表,见FireDAC数据库连接。

sensor_WU 博客 2562

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

FdxManager学习笔记

FdxManager是创建、管理和销毁FDX SDK的最核心的类。一个项目只有一个FdxManager,所以是单件模式。在项目开始时必须要第一步创建它。 FbxManager* lSdkManager = FbxManager::Create(); 当我们加载模型对象(FbxScene,可以是一个场景模型)时,必须由FdxManager来创建。对象名可以只是“” FbxScen

c522035458的专栏 997

多层结构中必不可少件TClientDataSet的全面剖析

多层结构中必不可少件TClientDataSet的全面剖析 Delphi常用日期函数 ClientDataSet 探讨   [ 日期:2005-06-19 ]   [ 来自:本站原创 ] ClientDataSet 探讨 1.    与TTable、TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端。很多...

weixin_33691700的博客 214

ClientDataSet中的PacketRecords属性,减轻网络负载,提升服务器与客户端性能

ClientDataSet.PacketRecords属性控制一次性从数据库服务器读取的数据记录条数,默认值-1(表示全部读取),如果数据量很大,会加重网络负载,影响服务器和客户端性能。将 PacketRecords设置成一合理的正值表示一次从数据库读取的数量,通常局域网设置成100-500,广域网设置成50-200,视自身需求适当调整,当浏览的数量超过时,会自动从服务器中读取PacketRec...

weixin_33893473的博客 511

delphi 中 Record ,packet Record

在windows中内存的分配一次是4个字节的。而packed按数据类型进行内存的申请和分配,读取时也是按照数据型的大小进行指针定位,这样速度要慢一些,因为需要额外的时间来进行指针的定位。因此如果不用packed的话,delphi将按一次4个字节的方式申请内存,因此如果一个变量没有4个字节宽的话也要占4个字节!这样就浪费了,你可以用packed关键字取消这种优化。例子:type4个字节1个字节end;typeend;

909

ClientDataSet 心得

ClientDataSet 心得

900

FireDAC 学习 - 3:建立数据库连接 之 TFDManager

使用数据库,第一步是建立和数据库的连接。结果关于连接,不是第一篇,而是本系列第三篇。 我使用 FireBird 开源数据库作为测试。FireDAC 支持 FireBird。 在本系列第一篇,我没有仔细说 FDConnection1 是如何与数据库建立连接的。我用了最简单的办法,也就是双击设计期拖到界面上的 FDConnection1,它会弹出一个对话框。在那个对话框里面进行设置就好了,如下图: 如上图,我指定 FireBird 数据库文件 TESTDATA.fdb 的全路径名称给 DataBase

pcplayer的博客 4413

【delphi】ClientDataSet详细解读

TClientDataSet的基本属性和方法   TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds/.xml,是基于文件型数据存储和操作的控件。   该控件封装了对数据进行操作处理的接口和功能,而本身并不依赖其它数据库驱动程序,基本上能满足单机"瘦"数据库应用程序的需要。 FieldDefs: 字段定义列表属性   可通过单击属性编辑器中的属性编...

weixin_33700350的博客 952
上一篇: Delphi DataSnap 初步入门使用总结
下一篇: Delphi XE10 序列化 TDictionary 为 JSON 的问题
pcplayer
博客等级 码龄26年 633粉丝 284原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值