☰
Delphi 13.1安装FibPlus控件:Firebird数据库连接实战指南
2026/9/25 1:19:49 网站建设 项目流程

简介:这套Delphi 13.1控件包面向使用Embarcadero Delphi进行数据库应用开发的工程师,提供FibPlus组件从Delphi 5到Delphi 13的完整源码、工程与文档,用于快速构建Oracle、MySQL、PostgreSQL等数据库连接、事务管理与断线重连功能,减少底层数据库访问代码的编写量。包体共435个文件,压缩后1.82MB,包含137个pas源码、68个dproj工程、55个dpk包定义、54个dfm窗体以及若干bcb项目、说明文档和SQL脚本,覆盖不同开发环境下的编译与部署需求。目前已有58人下载学习。通过该资源可获取FibPlus历代版本组件实现,便于在旧项目维护中复用,或在新项目中集成经长期验证的数据库访问层;同时,工程文件与源码结构完整,适合查阅组件内部机制、自定义扩展以及排查连接疑难问题。

1. Delphi 13.1 控件之 FibPlus:一个 7z 压缩包背后,是 Firebird 项目的兼容性出路

如果你手上有一个叫fibplus-D5-D13.7z的压缩包,多半是想在 Delphi 13.1 里继续用 FibPlus 控件。这套控件是 Firebird/InterBase 数据库的专业客户端组件,历史比 FireDAC 早得多,大量旧系统从 Delphi 5 一路写过来,代码里全是TpFIBDatabase、TpFIBQuery,换驱动等于重写业务层。FibPlus 能活到今天,靠的是源码级兼容多版本 Delphi:D5、D6、D7 一直到 D13,同一个包里有各版本 IDE 的工程文件,解压后自己编译即可安装。这篇笔记就按这个路径走:先拆包,再装包,然后连库排坑。

2. 为什么这套 D5~D13 控件包能顶替官方驱动:FibPlus 的定位与包结构

FIBPlus 不是 ORM,也不是通用数据库框架,它直接封装 Firebird/InterBase 客户端 API。这种“专精一个数据库”的定位,决定了它在处理生成器、事件、数组字段、PSQL 调用时,比通用组件更顺手,也更接近底层语义。很多老项目从 Delphi 7 迁移到新 IDE 时,官方 FireDAC 虽然功能强大,但代码迁移成本极高,而 FIBPlus 的单元名、组件名、属性名几乎不变,重编译就能跑。这个特性让它在中小型桌面系统里一直有一席之地。

2.1 选型逻辑:FIBPlus 和 FireDAC、dbExpress、Zeos 的差别

先看一张对比表,方便你判断自己该不该继续用 FibPlus。

维度FIBPlusFireDACdbExpressZeos
数据库定位只做 Firebird/InterBase多数据库通用多数据库通用(已边缘化)多数据库通用
老代码兼容性组件名几乎不变,迁移成本低需要换组件、换属性,改动大单向数据集,早已不维护接口与 TDataSet 兼容,但底层行为有差异
Firebird 特性支持生成器、事件、数组字段、PSQL 原生支持部分支持,需要绕不支持基础支持
部署复杂度只需要带 fbclient.dll 和源码编译出的 BPL驱动多、配置项多依赖驱动配置配置简单但大事务下性能一般
学习成本会 TDataSet 就会用需要熟悉 FireDAC 的 Connection 模型低低

从这个表能看出,如果项目跟 Firebird 深度绑定,特别是有大量生成器、事件、存储过程交互,FIBPlus 依然是省事的选择。FireDAC 当然也能连 Firebird,但你会发现自己总是在处理“通用抽象”和“数据库特性”之间的缝隙,比如事件回调、批量写入的方言差异。与其花两天改代码,不如花半天把旧控件在新 IDE 里编译一遍。

2.2 解压 fibplus-D5-D13.7z:先看目录结构,再决定用什么版本

拿到fibplus-D5-D13.7z,先用 7-Zip 解压到固定目录,比如D:\Components\FIBPlus。别解压到桌面或者临时目录,因为后面要反复给 IDE 加路径,目录一旦移动,Library Path 全部要重配。

常规的 FibPlus 包内会有这样几个目录:

目录/文件作用安装时怎么处理
Source或Source3232 位编译用的单元源码、公共 .inc 头文件加入 IDE 的 Library Path
Source6464 位编译用的 API 封装和连接库声明做 Win64 目标时加入
Package\D5~Package\D13各 Delphi 版本对应的 .dpk / .dproj 工程用 IDE 打开对应版本编译安装
Bpl/Dcu预编译产物或上次编译的输出不要直接拿来用,跨版本必坏

这里有个原则要记住:不同 Delphi 版本的编译器 ABI 不互通,预编译的 Dcu/Bpl 即使能装上,运行期也可能因为 RTL 版本不一致而报错。所以拿到包后,别去翻 Bpl 目录碰运气,直接找对应 D13 的源码工程自己编译。D13在这个包里对应的是新版本 Delphi 的工程目录,也就是你在 Delphi 13.1 里要打开的那一组。

解压后先把整个目录刷一遍杀毒,Fab 的包经常被安全软件误报 fbclient.dll 或 BPL 是风险文件。如果解压过程中被杀软隔离了控件文件,后面编译到一半会报“找不到 XXX.bpl”,特别耽误时间。下载页写了密码就先输入密码解压,解压完右键包文件 → 属性 → 底部“解除锁定”,这一步不做,IDE 打开 .dpk 时可能被 Windows 阻挡。

2.3 安装前检查:位数、杀毒与条件编译宏

Delphi 13.1 的 IDE 宿主进程是 32 位,但可以编译 Win32 和 Win64 目标。FIBPlus 包里的 D13 工程要确认它引用的到底是 Source32 还是 Source64。正常情况是:设计时包和运行时包都编译成 32 位,给 32 位 IDE 使用;你的业务项目如果要做 Win64,再单独把 Source64 里的单元编一遍。

另一个容易被忽略的点是条件编译宏。FIBPlus 源码里靠USE_FIREBIRD一类的宏区分 InterBase 和 Firebird 两种客户端 API。如果你连的是 Firebird 3/4/5,而宏没打开,编译期不报错,运行期连接时才会发现函数入口对不上,直接给你一个“Client library could not be loaded”或者干脆连不上。这个坑藏得深,等编译安装都做完了才发现会很折腾。

提示:安装前先把 IDE 或杀毒软件里对D:\Components\FIBPlus的实时防护关掉,等编译完再开。不是每个杀软都误报,但误报一次就够你排查半天。

3. 在 Delphi 13.1 里编译安装 FibPlus:从打开 .dpk 到拖出第一个连接

这一章是整个流程最核心的部分。FibPlus 不像普通第三方控件只需要复制一个 BPL 就能用,它需要在 IDE 里打开源码包工程,先编译再安装。步骤如下:先配源码搜索路径,再编译运行时包,最后安装设计时包。哪个前置没做好,后面都会以各种报错的方式提醒你。

3.1 先在 IDE 里把源码路径放对,后面才不会到处撞错

打开 Delphi 13.1,进入Tools → Options → Environment Options → Delphi Options → Library。在Library path里把 FIBPlus 的Source目录加进去。注意加的是Source根目录,不是Package\D13,因为 .dpk 编译时需要找到公共的头文件.inc和各个单元文件。Package\D13里只有工程文件,单元都在Source里。

Library path的排序也有讲究。如果这台机器装过旧版 FIBPlus,优先检查列表里有没有指向别的 FIBPlus 目录。多个版本的 FIBPlus 源码头文件同时存在,编译器会按搜索顺序取第一个匹配的.inc,一旦取到旧版,后面全是版本宏不匹配的报错。我的习惯是把新解压的目录放在最上面,然后把旧版本的路径全部删掉。

提示:同一台机器只留一份 FIBPlus 源码。混用版本是“签名字节不一致”“找不到单元”的头号原因。

3.2 编译设计时包与运行时包:点错的代价

进入Package\D13,正常情况下会看到两类工程文件:运行时包类似FibPlusD13.dpk,设计时包类似dclFibPlusD13.dpk。编译顺序必须是先运行时包,后设计时包。

在 IDE 中打开运行时包FibPlusD13.dpk,Project Manager 里右键工程节点,选Compile。这时 Messages 窗口会刷一段编译日志。看到Build成功之后,再打开设计时包dclFibPlusD13.dpk,右键Install。设计时包装完,组件面板会自动新增一个FIBPlus页面,里面是 TpFIBDatabase、TpFIBQuery、TpFIBTransaction 等一批组件。

如果你先装设计时包,IDE 会提示“无法加载包,因为另一个包尚未编译”。这时只要把顺序反过来就行,不需要重新解压。

编译失败的常见信息集中在 Messages 窗口的第一条错误:如果报Unit not found: pFIBDatabase.pas,那是第一步 Library Path 没配置对。如果报类似E2086的版本相关错误,多半是.inc里的 Delphi 版本宏和当前 IDE 不匹配,去Source下的公共头文件里找DELPHI_VERSION相关判断,把对应 D13 的分支打开。

3.3 最小验证工程:一个 TpFIBDatabase 连上本机 Firebird

安装成功后,立刻建一个 Blank VCL 项目来验证,不要直接开老项目。拖一个TpFIBDatabase和一个TpFIBTransaction到窗体上,把 Database 的Transaction属性指向事务组件。在OnBeforeConnect事件里写连接参数,代码如下:

procedure TForm1.pFIBDatabase1BeforeConnect(Sender: TObject); begin // 避免在 IDE 里硬填连接串,运行期赋值更适合分发给客户 pFIBDatabase1.DatabaseName := 'localhost:C:\Data\demo.fdb'; pFIBDatabase1.UserName := 'SYSDBA'; pFIBDatabase1.Password := 'masterkey'; pFIBDatabase1.SQLDialect := 3; pFIBDatabase1.LibraryName := 'fbclient.dll'; end;

这样做的原因是OnBeforeConnect在每次Connected := True之前触发,连接参数集中在一处,后期换数据库服务器地址只要改这一处。上面的代码里DatabaseName用的是本地连接串格式,localhost表示本机,C:\Data\demo.fdb是库文件路径。LibraryName := 'fbclient.dll'告诉控件加载哪个客户端库,如果你的 Firebird 是高版本,这里需要指定对应版本的客户端。

然后在FormShow里连接:

procedure TForm1.FormShow(Sender: TObject); begin // 故意放 FormShow 而不是 FormCreate,方便调试器捕获连库异常 pFIBDatabase1.Connected := True; end;

放 FormShow 是因为 FormCreate 阶段 IDE 的异常处理还不够友好,连不上库时弹出的不是直观的对话框,而是一个 IDE 级异常中断,新手容易被吓住。连库成功后,窗体运行起来没有任何异常,说明安装步骤已经全部走通。

4. 用 FibPlus 操作 Firebird:连接参数、事务和写入优化

安装好只是第一步,真正干活是在业务代码里。FIBPlus 的日常操作围绕TpFIBDatabase、TpFIBTransaction、TpFIBQuery和TpFIBDataset四个组件展开。连接参数决定能不能连上,事务决定数据一致性,而写入方式直接关系到性能和锁冲突。

4.1 TpFIBDatabase 连接参数速查:照着填就不会连不上

常见的连接属性如下表:

属性作用常用值备注
DatabaseName数据库名localhost:C:\Data\demo.fdb支持别名或完整路径
UserName/Password账号口令SYSDBA/masterkeyFirebird 默认账号,生产环境务必改
SQLDialectSQL 方言版本3老库可能是 1 或 2,不要盲目设 3
LibraryName客户端库文件名fbclient.dll32 位程序用 32 位 dll,64 位类似
Charset连接字符集UTF8/WIN1252/NONE直接影响中文是否乱码
TraceFlags日志跟踪开关[]调试时可打开看 SQL 发送情况

SQLDialect是最容易搞错的参数。Dialect 1 对应 InterBase 6 之前的老库,不支持CURRENT_TIMESTAMP等 SQL:2003 语法。如果你连的是老库却把 Dialect 设成 3,时间字段比较和字符串拼接会翻车。反之,新库用 Dialect 1 会因为语法受限而报错。最稳妥的做法是先问 DBA 或查数据库的RDB$DATABASE字段确认版本,再决定。

Charset更关键。Firebird 安装时默认字符集可能是NONE,但个别库建库时指定了UTF8或WIN1252。连接字符集和数据库实际字符集不一致,写入中文就可能变成问号。到了排查乱码那一步再来改字符集,往往还要配合数据库端的CONNECT语句,所以一开始就填UTF8最省事,前提是数据库本身能接受 UTF8 编码。

4.2 从查询到提交:TpFIBQuery 与显式事务的配合

用 FIBPlus 操作数据,尽量养成显式事务的习惯。下面这段代码是一次完整查询、修改、提交过程:

// 查询:按参数取订单 qry.SQL.Text := 'SELECT ID, NAME, AMOUNT FROM ORDERS WHERE CUST_ID = :CustID'; qry.ParamByName('CustID').AsInteger := 1001; qry.Open; // 修改:把金额更新为 99.90 qry.SQL.Text := 'UPDATE ORDERS SET AMOUNT = :Amount WHERE ID = :ID'; qry.ParamByName('Amount').AsCurrency := 99.90; qry.ParamByName('ID').AsInteger := 1; qry.ExecSQL; // 提交:一个事务里干完所有事再提交 pFIBTransaction1.Commit;

注意到这里没有写StartTransaction,因为 FIBPlus 在第一次执行 SQL 时会自动开启一个事务。如果你把TpFIBTransaction1连到了 Database 的默认事务属性上,这套流程是成立的。提交之后再来一个查询,事务会自动重新开启,不需要手动管。

但要小心 FIBPlus 老项目里常见的“一条 SQL 一个事务”习惯。有些代码把查询组件放在循环里,每循环一次就执行一次查询,然后提交一次。数据量小的时候没问题,到了几千条批量写入的场景,数据库端会产生大量事务记录,锁等待和日志膨胀都会来。要控制事务粒度,就把Commit移到循环外面,或者用显式事务包住一批写入。

4.3 取回生成器 ID 与批量写入:少一次查询,少一个锁

Firebird 的主键生成通常靠生成器(Sequence),老写法是先用GEN_ID取出下一个值,再拼 INSERT。这个做法在并发下容易重复,因为两个客户端可能同时取到同一个值。新写法是用INSERT ... RETURNING子句,核心代码:

qry.SQL.Text := 'INSERT INTO ORDERS (ID, NAME) ' + 'VALUES (GEN_ID(GEN_ORDERS_ID, 1), :Name) RETURNING ID'; qry.ParamByName('Name').AsString := 'test订单'; qry.Open; // 用 Open 而不是 ExecSQL,因为要取返回结果 id := qry.FieldByName('ID').AsInteger;

这里必须用Open而不是ExecSQL,因为RETURNING会返回一行结果。如果你用ExecSQL,返回值不会进入结果集,FieldByName('ID')会报找不到字段。这个写法要求 Firebird 2.1 以上和 Dialect 3,适用范围其实挺广的。

批量写入时还有一个技巧:把多条 INSERT 放在一句EXECUTE BLOCK里。FIBPlus 能直接执行这段 PSQL,一次往返完成多条插入,网络开销小很多。但EXECUTE BLOCK内不能使用参数,数量不固定时就得循环拼 SQL,注意别让字符串拼接产生注入风险。

5. Delphi 13.1 下 FibPlus 的 5 个踩坑常见问题和排查记录

从安装到运行,FIBPlus 的坑集中在版本混用、位数不匹配、字符集和事务这四类。下面按现象描述、原因分析、解决办法三步来写,都是实操里真实撞过的墙。

5.1 组件面板找不到 FIBPlus 页:多半是安装了旧的 BPL

  • 现象:设计时包安装成功提示了,但打开窗体后组件面板里找不到FIBPlus页,或者页里组件是灰的。
  • 原因:最常见的是这台机器装过老版本 FIBPlus,Component → Install Packages里旧包还在,新装的 BPL 被 IDE 忽略了。另一种情况是旧 BPL 残留在SysWOW64或 Windows 系统目录,新包装完后被系统目录里的旧文件干扰。
  • 解决:先到Component → Install Packages里把所有 FIBPlus 相关包卸载,再到 IDE 安装目录下的Bpl里删除残留的dclFibPlus*.bpl。清理干净后重新打开 D13 的设计时包,再 Install 一次。装完后如果还是看不到,手动点Install Packages右下角的Add,把新编译出来的dclFibPlusD13.bpl加进去。

这个坑本质上是“系统上存在两份包”,编译环境指认了其中一份,IDE 又加载了另一份。清理旧包比重装新包更重要。

5.2 编译报错 Unit not found: pFIBDatabase.pas:版本混用的黑匣子

  • 现象:新建项目后,在单元里uses了 FIBPlus 的单元,编译时提示找不到pFIBDatabase.pas或类似单元。
  • 原因:全局 Library Path 没加对,或者加的顺序不对。注意一个隐藏问题:Library Path 加的是 Source 根目录,但Source下面还分多层子目录,某些包需要把子目录也加进去,比如Source\Source32。编译器只在 Library Path 指定的目录里找单元,子目录不会自动递归。
  • 解决:回到Tools → Options → Delphi Options → Library,把Source根目录和必要的子目录都加进 Library Path,目录之间用分号分隔。加完点Save,关掉 IDE 重新打开项目,让路径配置彻底加载。如果还报同样的错,搜索整个Source目录确认真的有pFIBDatabase.pas,没有就说明包不完整,需要换一份完整的源码包。

一个更隐蔽的变体是编译老项目时,项目自身库路径里也配了一份 FIBPlus 旧路径,IDE 会优先使用项目级路径。这时候要在Project → Options → Delphi Compiler → Search Path里把新路径加进去,否则全局 Library Path 根本不生效。

5.3 Win64 目标编译失败:fbclient.dll 位数不对

  • 现象:32 位项目一切正常,切换 Win64 目标平台后编译报错,提示无法解析外部符号或加载fbclient.dll失败。
  • 原因:FIBPlus 的 64 位支持依赖独立的 Source64 目录。如果工程没有把 Source64 加到搜索路径,编译器沿用的还是 32 位单元声明。另一个原因是运行时找不到 64 位fbclient.dll:64 位程序不能加载 32 位客户端库,Windows 64 位系统下 System32 里的是 64 位版本,SysWOW64 里是 32 位版本,放错位置会直接报加载失败。
  • 解决:在项目搜索路径里把 FIBPlus 的Source64目录加进去,删掉原来的 Source32 路径。然后把程序要用的 64 位fbclient.dll放到 exe 同目录下,并确认LibraryName不指向绝对路径。更保险的做法是在 FormCreate 里用pFIBDatabase1.LibraryName := 'fbclient.dll',运行时按当前进程位数加载。

5.4 中文乱码:Charset 不是摆设

  • 现象:查询出来的中文显示成乱码,写入的中文再从库里读出来也是问号。有时候同一段代码在 A 机器正常,在 B 机器就乱码。
  • 原因:Firebird 的字符集不是“数据库里存成什么就是什么”,连接字符集与数据库字符集不一致,客户端 API 会做转换,转换失败就成了问号。常见错误是连接属性里Charset不填,默认NONE表示不转换,数据如何进库就如何出库。
  • 解决:在OnBeforeConnect里把Charset := 'UTF8',并确认数据库本身是用 UTF8 创建的。如果数据库建库时用的是WIN1252,你把它当 UTF8 连,转换照样会出错。另外,低版本的fbclient.dll对 UTF8 支持有缺陷,建议把客户端库升级到与你 Firebird 服务端匹配的版本。

提示:乱码问题如果死在“改完连接字符集还乱”,去查数据库建库脚本的DEFAULT CHARACTER SET字段,两边都得对上才会好。

5.5 写入超时与死锁:事务没提交是头号血泪经验

  • 现象:单用户测试写入正常,多用户一上来就报锁等待超时,甚至deadlock。日志里频繁出现lock conflict on no wait transaction。
  • 原因:FIBPlus 的查询组件默认可能在执行SELECT时开了一个写事务,如果代码里没有及时 Commit 或 Rollback,事务一直占着记录版本。Firebird 的多版本并发机制下,其他会话修改同一行时会等待锁释放,等待时间超过服务端配置就报超时。
  • 解决:先看业务代码里每个查询后面有没有 Commit 或 Rollback。一个简便的排查办法是在事务组件的AfterCommit事件里写一个日志,统计每次事务持续时间。事务粒度尽量小,循环内不要提交,循环外提交一次。另一个方向是把事务组件的 Wait 属性设为 True,并配置合理的 Lock Timeout,这样至少不会一条锁冲突直接让整个程序崩溃,而是等待超时后给出明确异常。

这个坑是老代码里最普遍的。很多人从 Delphi 7 时代一路带过来的写法就是“开了连接不关事务”,以前数据量小没事,现在数据一多必然爆发。

6. 连接不稳定时的最后防线:FibPlus 日志与自动重连的实战写法

数据库连接在客户现场经常遇到半夜断线、网络抖动导致连接失效的情况。给 FIBPlus 程序加一个定时重连机制,是桌面系统长期稳定运行的兜底做法。我的习惯是开一个全局定时器,每秒检查一次连接状态,断线就尝试重连,重连失败写日志。

procedure TForm1.TimerReconnectTimer(Sender: TObject); begin if pFIBDatabase1.Connected then Exit; try pFIBDatabase1.Connected := True; // 如果断线前有未完成事务,必须回滚,否则新查询会报事务状态异常 if pFIBTransaction1.InTransaction then pFIBTransaction1.Rollback; except // 这里只记录日志,不弹对话框,避免每秒钟都打扰用户 LogEvent('重连失败: ' + DateTimeToStr(Now)); end; end;

这段代码的精髓在InTransaction判断后主动Rollback。很多重连机制只做Connected := True,忘了旧事务没有结束,Firebird 会拒绝在新事务开启前提交老事务,结果重连成功后下一句 SQL 还是报错。调试这类问题,我会把TraceFlags打开,把 FIBPlus 发送的每条 SQL 和事务边界打到日志文件里,能直接看到每次COMMIT和ROLLBACK的触发时机。

至于日志组件,FIBPlus 自带了一套日志机制,也可以在TpFIBDatabase的各个事件里自己接管。我的做法是在 FormCreate 时指定一个日志文件路径,然后把TraceFlags里的执行计划、参数值选项打开,这样客户现场出问题,拿回来一份日志就能还原 SQL 执行顺序,少跑很多冤枉路。自动重连的定时器间隔不要低于 3 秒,不然网络抖动恢复期间会连续发起连接请求,把服务器端口占满。

用 FIBPlus 写跨十年的桌面系统,我的最大教训是:装控件不怕编译报错,怕的是同一台机器上版本混用后留下的隐性坑。换环境时先把旧包装干净、路径清干净,再上新包,能省掉一半的血泪时间。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询