再谈 Firebird / Interbase 自增字段和WebService MIDAS 框架下的 ClientDataSet

Firebird数据库Firebird.dll供VB6使用:C++dll源码和VB6 Demo源码演示 仅一个Win32 dll (非COM, 可直接使用), 让VB6拥有强大而不复杂的Firebird数据库,包含C++dll源码和VB6 Demo源码演示 firebird是一个全功能的,强大高效的,轻量级,免维护的数据库。它很容易让您从单用户,单数据库升级到企业级的应用,火鸟是提供许多 ANSI SQL 标准功能关系数据库,提供优秀的并发性、 高性能和对存储的过程和触发器的功能强大的语言支持。 firebird是一个十分小的开源数据库,可作为像Access一样使用的文件型数据库,单用户连接;也能够以服务方式启动,支持多用户访问 立即下载

架构:

1. 数据库服务器:FireBird;

2. WebService 服务器端,采用 FireDAC 控件 + DataSetProvider;

3. WebService 客户端,采用 ClientDataSet 绑定到服务器端的 DataSetProvider;

4. 数据库表名:TEST,有2个字段:XUHAO, DESC;其中 XUHAO 是整数,我希望它是个顺序自增的字段,是主键,也是本文关注处理的对象。

代码需求

上述架构下,连接数据库的控件,采用 FireDAC 还是其它控件,和本主题无关。虽然 FireDAC 控件也能处理 FireBird 的自增字段,我之前有文章写这个 -- 请见:再谈 Firebird / Interbase 自增字段和 FireDAC 以及 ClientDataSet

但在三层 WebService 架构下,上述方法比较麻烦,用不上。

在上述架构下,有几个前提是必须的:

1. XUHAO 字段是主键,因此在 ClientDataSet1 里面,新增记录,不能空,必须填值。又因为它的值是数据库服务器赋予的,是自增的,因此在客户端的 ClientDataSet1 里面,新增记录,填入负数值作为填充。

2. 在 WebService 架构下,ClientDataSet 和服务器端的 DataSetProvider1 是绑定的。

3. 尽量少写代码;

4. 尽量减少网络来回和网络数据量。

解决方案

方案一:

1. FireBird 数据库里面,为自增值,创建一个【生成器】。

2. FireBird 数据库里面,创建一个存储过程,这个存储过程调用生成器,获得一个唯一的增加值。存储过程代码如下:

BEGIN
  /* Procedure body */
  NEW_XUHAO = GEN_ID(TEST_XUHAO, 1);
  SUSPEND;
END

3. 在 WebService 服务器端的 SoapDataModule 里面,放一个 FdStoreProc 这个是 FireDAC 的用于存储过程的控件。将这个控件指向数据库的上述存储过程。写一个函数名为 GetNewXuHao,函数里面执行这个存储过程,获得最新的自增值;

4. 服务器端的 DataSetProvider 的 BeforeUpdateRecord 事件写入代码:

procedure TtestAutoInc.DataSetProvider1BeforeUpdateRecord(Sender: TObject;
  SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
  var Applied: Boolean);
begin
  if UpdateKind = ukInsert then
    DeltaDS.FieldByName('XuHao').NewValue := GetNewXuHao;
end;

上述代码,利用数据库的存储过程,从数据库获得唯一的自增值,将来自客户端提交的新增字段的 XUHAO 字段值,修改为数据库产生的值。

4.1. 同时,设置 DataSetProvider1.Options 的 poPropogateChanges 设置为 True (设计期勾选上);

4.2. 因为在服务器端修改了 DataSetProvider1 里面的 DeltaDS 的 XUHAO 字段值,又设置了上述属性,则客户端 ClientDataSet1.ApplyUpdates(0) 提交后,会自动获得服务器端修改的值,自动将新增记录的负数值变为正确的值。

到此问题搞定。

方案二:

第一个方案,服务器端需要做不少事,写不少代码,去调用数据库的存储过程等。如果绕开服务器端直接操作数据库,则自增不存在。严重依赖服务器端代码。

对于 FireBird 数据库来说,可以做一个真正的自增字段。实现方法是:

A. 仍然需要一个生成器,用于产生顺序自增的数字;

B. 一个绑定到 Insert 新增记录的触发器,当数据库插入新纪录时,为记录产生一个自增值。触发器代码如下:

CREATE TRIGGER BI_LOG_XUHAO FOR "LOG"
ACTIVE BEFORE 
  INSERT
POSITION 0
AS
BEGIN
  NEW.XUHAO = GEN_ID(LOG_XUHAO_GEN, 1);
END;

实现了上述触发器,对于这个字段来说,就是个自增字段。只要增加一条记录,数据库就自动为这个新纪录自动插入一个最新的由生成器产生的唯一数字。和数据库之外的代码无关。

问题来了,客户端 ClientDataset1 插入一条记录并提交后,如何更新,获得数据库自己产生的自增值?

此时,方案一的办法不灵了。除非想办法获得数据库对应的新纪录的值。网上有一些方法,但毕竟麻烦也不易懂,而且代码和具体的数据库有关。

对于客户端来说:

1. 首先要做点事情,就是每增加一条新纪录,把 XUHAO 字段的值,自动赋值为负数,避免因为它是主键导致没有值带来的键值冲突异常。当然,要求用户手动输入也是可以的。自动的代码如下,在 ClientDataSet1 的 AfterInsert 事件里面写代码:

procedure TForm2.ClientDataSet1AfterInsert(DataSet: TDataSet);
var
  i: Integer;
begin
  i := ClientDataSet1.Tag - 1;
  ClientDataSet1.FieldByName('XUHAO').AsInteger := i;
  ClientDataSet1.Tag := i;
end;

2. 提交成功后,最简单的做法:ClientDataSet1.Refresh;就可以刷新。马上,就可以看到 XUHAO 自动新插入的记录的负数,变成了数据库对应该记录产生的新的自增数字。

但是,简单的 Refresh 的问题是网络数据流量大,尤其是当数据库里面记录特别多的时候。如果肯定该表不会有太多数据,可以采用这个简单办法,少写代码。

2.1. ClientDataSet1.Refresh 会清空当前记录;

2.2. 然后,从服务器端的 DataSetProvider 请求全部数据。这样带来网络流量大的问题。

解决网络流量的问题:

既然 XUHAO 是一个整数主键,那么,SQL 语句可以写成:

select * from TEST where XUHAO>:XUHAO

然后,运行服务器,在设计期 IDE 里面,右键点 ClientDataSet1,下拉菜单选择 Fetch Params,它自动获取到参数。参数存在 ClientDataSet1 的 Params 属性里面,如果获取成功,看属性面板对应项目就能看到。

然后在 ClientDataSet1 的 BeforeRefresh 事件里面,对参数赋值,服务器端的 SQL 语句自动获得该参数。只要赋值正确,抓取的数据就只是最新的数据,降低了网络数据流量。代码如下:

procedure TForm2.ClientDataSet1BeforeOpen(DataSet: TDataSet);
begin
  ClientDataSet1.Params[0].Value := -1
end;
procedure TForm2.ClientDataSet1BeforeRefresh(DataSet: TDataSet);
var
  i: Integer;
begin
  FData := ClientDataset1.Data;  //这个 FData: Variant; 全局的。
  CLientDataSet1.Last;
  i := ClientDataSet1.FieldByName('XuHao').Value;

  ClientDataSet1.Params[0].Value := i;
end;
procedure TForm2.ClientDataSet1AfterRefresh(DataSet: TDataSet);
begin
  ClientDataset1.AppendData(FData, True);

  with ClientDataSet1 do
  begin
    //刷新后,负数记录还在,对于负数记录新增的记录也拉回来了。因此要清除掉负数记录。
    First;
    while not Eof do
    begin
      if FieldByName('XuHao').AsInteger < 0 then
      begin
        Delete;
      end
      else Next;
    end;

    MergeChangeLog;
  end;
end;

上述代码解释:

1. OnOpen 事件,第一次打开,参数赋值 -1,获得全部记录;

2. BeforeRefresh 事件,获取当前最大编号,赋值给参数。这里使用了 LAST,所以必须要先把 XUHAO 作为索引,让它自动排序。这里我是设计期完成,因此没有设置索引的代码。

3. AfterRefresh 事件,因为只抓取了最新插入的记录,因此:A. 把原来的记录加回来;B. 把负数的记录删除掉。

到此完成。这个方法的好处是,所有代码是在客户端完成,服务器端的代码是正常的代码,可以应对任何需求。数据库完成自增,也无需服务器端的 Delphi 代码干预,耦合度更低。

中文版:InterBase/FireBird数据库编程从入门到精通 从来没有过这么一种数据库,能够像InterBase/FireBird一样富有激情。这是一种完全为程序员准备的数据库,就像瑞士军刀一样小巧、方便、实用。以往的数据库,不是太大太笨重(例如,Oracle、MS SQL、DB2),就是太简陋,功能不足(例如My SQL)。而InterBase/FireBird则是在两者之间找到了一个很好的平衡点,笔者不妨称之为“中型数据库”。随着硬件环境的不断发展,普通的个人电脑的计算能力越来越逼近并不太久以前的大型计算机的能力,这种趋势同时也大大推动了与此相适应的中型数据库的应用。中型数据库逐渐蚕食大型数据库的市场,这几乎是一个明显的趋势。随着软硬件条件的不断发展,很多大型数据库的很多极其复杂的特性,今天看来逐渐成为了不必要。今天的软件用户更加渴求“简单、实用、绿色”。InterBase/FireBird数据库几乎就是为这个宗旨而量身定制的。....................... 立即下载

相关推荐

5分钟搞定阿里云千问大模型API申请:手把手教你获取API Key

本文提供了一份高效的阿里云通义千问大模型API Key获取实战指南。通过清晰的步骤,帮助开发者在五分钟内完成从账号准备、精准导航控制台到创建并验证API Key的全过程,并强调了密钥安全管理和基础调用测试的重要性,助力快速集成AI能力。

ol789012345的博客 1345

7 大开源数据库利弊全对比

1、CUBRID CUBRID 是一个很好的免费开源选择,专门针对 Web 应用程序进行优化,当复杂的 Web 服务需要处理大量数据并生成巨大的并发请求时,CUBRID 非常有用。这个解决方案是用 C 写的。 优点: 多粒度锁定 在线备份 用于开发语言的 GUI 工具和驱动程序: JDBC, PHP, Python, Perl, 和 Ruby. ...

顺其自然~专栏 2490

Simulink封装与库的建立

第二栏设置标签,第三栏是对应变量名,即是第一张图中的常量名。1.先将输入与常量模块相连接并生成子系统。按照如图所示添加修改,最后的效果如下图。封装子系统搭建测试环境。

lensyu1994的博客 1741

firebird数据库安装连接的一些常见错误及解决方法

firebird数据库安装连接的一些常见错误及解决方法

hcy19970721的博客 5504

特性阻抗 – SI/PI 世界碰撞的地方

除了谐振零点和峰值外,在一定频率下,传输线的阻抗看起来像远端开路时的电容器的阻抗,也看起来像远端短路时电感的阻抗。如果随后的制造变化将测得的阻抗推到 -10% 容差的低端(例如 44 欧姆)的测量区域内,那么如果在初始下降时测量,则真正的特性阻抗将在 42 欧姆时降低 5%,并且超出规格。这意味着,当我们测量红色或蓝色图的峰和相邻谷之间的中间阻抗时,它是该频率下传输线的特性阻抗。图 7 远端开路时(红色常亮)与远端短路时(蓝色常亮)的电感和电容抗阻抗与频率的关系(上图)和传输线的阻抗与频率(下图)的对比。

jkh920184196的博客 962

从SSD到UFS:3分钟搞懂存储技术进化史(含最新协议对比)

本文梳理了从SSD到UFS的存储技术演进历程,重点解析了eMMC与UFS在架构上的核心差异。UFS凭借高速串行全双工接口,实现了性能与能效的飞跃。文章还对比了最新的UFS 4.0与PCIe 5.0 SSD协议,并探讨了3D NAND、SLC缓存等底层技术,揭示了移动与PC存储技术融合的未来趋势。

weixin_29294597的博客 279

推荐!DBeaver 开源免费 功能强大的 数据库管理工具

(后续,还是转回mysql了,直接用的mysql5.7,支持win7的32位。DBeaver是一个流行的开源数据库管理工具,支持多种数据库管理系统(如MySQL、PostgreSQL、Oracle、SQLite、Firebird等),并具有简单易用的用户界面和强大的功能,例如数据导入/导出、数据查询、视图管理、SQL编辑器等。所以想把mysql换成firebird,省了每次安装程序的时候还要安装MySQL。而且,中文有遇到乱码的问题。后来找了好久发现了DBeaver,可以连接不同的数据库,并导入导出数据。

MANYOUZSH的专栏 1247

PyCharm高效配置Gitee全攻略

本文介绍了如何在PyCharm和VS Code中配置Gitee插件并管理代码。主要内容包括:1) PyCharm连接Gitee的配置步骤;2) 代码拉取与冲突解决方法;3) VS Code界面功能区域详解;4) 完整的代码提交流程(暂存→提交→推送)。特别说明了VS Code中Git面板的使用方法,以及推送代码到Gitee远程仓库的具体操作步骤。文章还提供了解决代码冲突的建议和注意事项,帮助开发者更好地进行版本控制。

ZhangJiqun&191cm&85kg 298

Firebird 数据库使用心得

      本人想做一个桌面应用,需要一个免安装的嵌入式关系数据库,在对比了 Access 和 Firebird 之后,选择了更简便、性能更好的后者。Firebird 简介:      firebird是一个真正的关系数据库,支持存储过程、视图、触发器、事务等大型关系数据库的所有特性,它是一个开源的,可以自由使用的数据库(即使是商业上的使用)。具有以下的特点:  支持原

HiSpring的专栏 9059

vscode配置matlab工作环境

前面有两篇文章我们分别讲了在vscode里面如何配置C语言环境和python环境,那两篇文章总体来说比较复杂,当然这篇也有许多有趣的问题。 附上链接: 文章目录matlab简介基本要求code runner插件与matlab相关的插件添加路径小结code runner是否支持更多语言更多选择另一个选择 matlab简介 MATLAB是美国MathWorks公司出品的商业数学软件,用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人,控制系统等领域。 MATLAB是ma

Cachel Wood的博客 4540

基于Simulink的无线充电系统LCC补偿网络建模与控制

本文详细介绍了基于Simulink的无线充电系统LCC补偿网络建模与控制方法。首先分析了LCC补偿网络的恒流输出、软开关实现和抗偏移能力等优势,并对比了不同补偿拓扑特性。随后分步骤讲解了Simulink建模流程,包括LCC主电路构建、关键参数设计、双闭环控制系统实现等核心环节。重点阐述了移相控制策略和软开关验证方法,提供了系统效率计算和抗偏移测试的调试技巧。最后展示了仿真结果,在耦合系数变化20%时,闭环系统仍能保持输出电压稳定在±2%波动范围内。文章还探讨了工程扩展方向,并针对常见问题给出了解决方案,为无

xiaoheshang_123的博客 539

Linux下的FireBird 数据库

Linux下的FireBird 数据库   2000年7月,Borland(即现在的Inprise)公司公布了其数据库产品Interbase的源代码。Firebird数据库就是从该数据库 中派生出来的。当时,Interbase是与客户/服务器版本的 Delphi产品捆绑在一些销售的。现在,Interbase已经变成了一只开放源码中的“火鸟”。   为什么要使用Firebird?   也许...

代码民工 1156

华为OD机试 双机位A卷 - 流量波峰 (C++ & Python & JAVA & JS & GO)

华为OD机试双机位A卷 流量波峰,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 1377

FIREBIRD浅历

firebird可以说是这个世界上最小而又支持存储过程的数据库,才3M而已,如果做小型应用,比ms sql(桌面版也有70多M),mysql(20-30M),方便的多。(一)数据库操作在开始-程序-Firebrid_2_0中执行Firebrid ISQL tool 出现SQL>输入SQL>CREATE DATABASE ‘e:/sams.fdb; 回车提示错误,……..,郁闷,一查资

godson_h的专栏 4409

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

现阶段的主流数据库分别是哪几种?

缓存一般用来保存一些进程被存取的对象或数据,通过缓存来存取对象或数据要比在磁盘上存取快很多,前者是内存,后者是磁盘、Memcached是一种纯内存缓存系统,把经常存取的对象或数据缓存在memcached的内存中,这些被缓存的数据被程序通过API的方式被读取,memcached里面的数据就像一张巨大的hash表,数据以key-value对的方式存在。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

2950

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【转】Firebird数据库值得信赖吗?为什么我要在开发中选择它?

Firebird数据库值得信赖吗?为什么我要在开发中选择它? 1、Firebird是一个真正的关系数据库,支持存储过程、视图、触发器、事务等大型关系数据库的所有特性;2、Firebird支持SQL92的绝大部分命令,并且支持大部分SQL99命令,新版Firebird 2.0对SQL99的支持更完整;3、Firebird源码基于成熟的商业数据库Interbase,有良好的稳定性,与Interbase有良好的兼容性;4、不用考虑授权费用(免费),不用当心将来有一天你或你的客户因为使用盗版而被数据库开发商告上法庭

Tirecoed的专栏 1669

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

数据库选型和FireBird的使用

<br />最近因为要做一个小的 项目,开发工具为Delphi,数据库选型进行了一些比较,最终决定采用FireBird数据库,各种数据库的优缺点分析如下:<br /><br />一、Firbird<br /><br />优点<br />1、Firebird是开 源免费的数据库,且诞生很多年了,比较稳定。<br />2、支持单机嵌入式开发, 单机版支持存储过程和触发器。<br />3、单机版和服务器版数据 库文件格式相同,升级至网络版简单。<br />4、跨平台,支持 window、linux<br

无名剑 1925

NonSQL数据库简介

<br />转自:http://blog.youkuaiyun.com/kk5595/archive/2011/01/04/6115950.aspx<br />【IT168 评论】 几乎每个Web开发人员都有自己喜欢的数据库,或自己最熟悉的数据库,但最常见的无外乎以下几种:<br />  MySQL<br />  PostgreSQL<br />  MSSQL<br />  SQLite<br />  MS Access<br />  或是更简单的XML,文本文件等。这些数据库有优秀的文档,背后有强大的社区支持,大部分

1030

FireBird Embedded学习日记

FireBird Embedded学习日记,有些内容还不太理解,欢迎大家指正.

u013727899的博客 8052

使用FireBird数据库基本知识

1.进安装目录bin文件夹,如果是3.0版本到根目录即可 2.数据库用户管理,使用命令:gesc -user sysdba - password masterkey    添加新用户:add huiqing -pw 123456 3.操作数据库:isql -user sysdba -password masterkey    创建数据库;create database 'c:\test.f

不敲代码的码农的博客 2万+

Firebird一款很牛X的数据库

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34297300的博客 1406

Borland DataSnap(MIDAS)三层架构编程中,DataSetProvider的Option属性

DataSetProvider的Option属性 看看远端数据模块里的DataSetProvider的Option属性是否设置正确!Provider控件的Options属性值是一个集合,用于设置有关打包和传递的选项,像显示哪些字段、允许哪种更新方式等等。1.         poFetchBlobsOnDemand:若包含此项,则表示数据包中不包括BLOB字段。不过,如果客户端的Tcl

abin30的专栏 1123

Delphi clientdataset的详细介绍

http://www.cnblogs.com/yplong/archive/2013/02/23/2923473.html delphi Midas SQLServer的自增字段的处理1.新增时,表中有自增字段,但是不希望用Refresh,直接ApplyUpdates直接看见自增字段的值在DataSetProvider.AfterUpdateRecord写如下代码 +

632

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 10.4.2 社区版开发的 APP 在 Google play 发布成功
下一篇: 虚拟机里的 MacOS 硬盘扩容
pcplayer
博客等级 码龄26年 633粉丝 284原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值