
简介这是为 Delphi 13.1 量身定制的 HeidiSQL 数据库管理控件包面向需要在 Windows 应用中操作 MySQL、MariaDB、PostgreSQL、SQL Server 等数据库的 Delphi 开发人员。它将 HeidiSQL 的图形化管理能力封装成与 IDE 无缝集成的组件免去手写复杂 SQL 和频繁切换外部工具的麻烦既适用于快速数据查询编辑也能支撑企业级数据库维护系统的开发。压缩包共 751 个文件大小约 29.8MB以 Pascal 源码单元pas、窗体定义dfm、图标与界面图片png/ico/bmp以及动态库dll为主另含编译资源脚本、项目与组件包工程文件、示例程序及说明文档方便在 Delphi 13.1 中直接加载、编译和二次扩展。控件除常规增删改查外还支持数据同步、备份恢复、多线程与异步数据库操作有助于降低延迟并应对大数据量场景。已有 49 人浏览学习适合正在使用 Delphi 13.1 构建数据库应用、期待提升数据层开发效率的中高级开发者。1. HeidiSQL 12.12 控件包Delphi 开发者为什么值得装它做数据库桌面工具最耗时的往往不是 SQL 本身而是那套看得见的壳连接管理、SQL 编辑器、表格数据维护。HeidiSQL 12.12 本身就是 Delphi 写出来的开源工具于是有人把它的核心模块拆成控件包让 Delphi 13.1 工程里能直接放 THeidiSession、THeidiQuery、THeidiGrid 这类设计时控件。这个 zip 里的 D123 构建标识表示它是面向 13.1 编译器匹配过的版本。如果你正在学习 Delphi 并且想抄一套成熟的数据库产品界面或者项目里正好需要“连接管理 SQL 编辑器 数据网格”三件套这套控件能省下两三个月的自研时间。它解决的不是“不会写 SQL 编辑器”的问题而是“不想维护 SQL 编辑器”的问题。适合的读者用 Delphi 做桌面工具、MIS、后台管理系统的开发者以及想通过读源码理解 Delphi 大型项目组织方式的进阶学习者。2. HeidiSQL 12.12 为什么能被做成 Delphi 控件模块边界与打包逻辑HeidiSQL 是一个用 VCL 写成的成熟数据库客户端它的主程序、连接管理、SQL 编辑器、数据网格之间本来就有清晰的分层。正因如此第三方才能把它的核心交互层抽出来封装成设计时控件而不是把整个 EXE 塞进你的项目里。理解这个模块边界比急着装包更重要——它决定了你能在代码里调用哪些能力、哪些能力仍然藏在控件内部。2.1 连接层、编辑器、数据网格控件的三件套拆包逻辑HeidiSQL 的界面可以分为四块左边是数据库连接树右边上半是 SQL 编辑器右边下半是查询结果网格顶部是工具栏和会话标签页。这四块在源码里分别对应不同的单元和窗体所以封装者可以只挑最常用的三块做成控件会话层封装连接参数和连接生命周期查询层封装 SQL 执行和结果集读取网格层封装表数据浏览和编辑。常见封装方式是提供三个核心类THeidiSession 管连接THeidiQuery 管 SQLTHeidiGrid 管数据展示。THeidiSession 还承担了数据库类型枚举比如 MySQL、MariaDB、PostgreSQL、Microsoft SQL Server不同连接器只是它内部的一个枚举值。这个设计跟 HeidiSQL 源码里的连接抽象保持一致。对使用者来说这个边界意味着两件事第一你不需要关心底层是 ADO 还是 dbExpress控件内部用自己的连接实现第二你可以单独用 Session 执行 SQL也可以把 Session 和 Grid 组合成一个内嵌的数据库浏览器。实际项目里最常见的组合是“左边树选表右边网格看数据”这就回到了 HeidiSQL 的产品形态。提示控件包不是把整个 HeidiSQL EXE 嵌进来它只是把 HeidiSQL 的源码模块编译成 BPL/DCP 形式的 Delphi 包。所以你的程序体积不会凭空多出几十 MB但功能上确实复用了 HeidiSQL 那套经过多年打磨的交互逻辑。2.2 D123 构建标识与 Delphi 13.1 的版本匹配关系Delphi 的包有一个容易被新手忽略的性质BPL 和 DCP 跟编译器版本强绑定。你在 Delphi 12 里编译出来的 .bpl 包装进 13.1 的 IDE轻则面板上不显示重则直接报“VCL 版本不匹配”或者加载失败。这是因为包在编译时会把自己的 Runtime 版本号写进二进制元数据IDE 加载时严格校验。这个 zip 名里的 D123我理解是一个面向 Delphi 13.1 的构建标记。D 表示 Delphi 编译目标123 是内部构建序号或适配版本号。跟从网上随便下到的“HeidiSQL 控件”相比带明确构建标识的包至少说明了作者做过版本对齐。你在安装前要做的第一件事就是确认这个 D123 不是给 Delphi 12 或 10.4 用的旧产物。包内文件的角色也需要认清。常见布局是source 目录放 .dpk 工程文件、.pas 源文件、.dfm 窗体文件bin 或 output 目录放预编译出来的 .bpl、.dcp、.res 文件。文件后缀和作用的对应关系如下文件后缀作用正确放置位置.dpkDelphi 包工程文件设计时和运行时各一个用 IDE 打开编译.bpl编译产物运行时组件库IDE 加载的实体IDE 安装包列表里登记.dcp编译符号文件类似 .dcu 的聚合索引Delphi 库路径里能找到.pas源码单元调试和跟踪时必需Library Path 指向的目录.res资源文件包图标和版本信息随编译自动读取2.3 最小编程模型Session 先于连接连接先于查询封装后的控件模型保留了 HeidiSQL 原来的思路Session 是顶层容器它负责连接参数的保存和连接生命周期Query 从属于 Session不能脱离 Session 单独使用Grid 则是纯展示组件它消费 Query 的结果集。只要记住这个层级写代码时就不会弄混变量的生命周期。下面是最小的代码骨架描述 Session 如何创建、连接、执行查询并释放uses HeidiQLib, // 控件包主命名空间 HeidiQLib.Core; // 核心类型定义 procedure TForm1.BtnQueryClick(Sender: TObject); var LSession: THeidiSession; LQuery: THeidiQuery; begin LSession : THeidiSession.Create(nil); try // 连接参数直接在 Session 上设置 LSession.ConnectorType : ctMariaDB; LSession.Hostname : 192.168.1.20; LSession.Port : 3306; LSession.Username : root; LSession.Password : Pssw0rd; LSession.Charset : utf8mb4; // Connect 内部做 TCP 连接、握手、字符集协商 LSession.Connect; // Query 从 Session 派生结果集跟随 Session 生命周期 LQuery : LSession.NewQuery; try LQuery.SQL.Text : SELECT id, name, created_at FROM orders LIMIT 100; LQuery.Open; while not LQuery.Eof do begin Memo1.Lines.Add(LQuery.FieldByName(name).AsString); LQuery.Next; end; finally LQuery.Free; end; finally // Session 释放时会自动断开连接无需手动 Disconnect LSession.Free; end; end;这段代码有三个参数值得注意。ConnectorType 决定走哪套客户端库选错会在连接时报协议错误Charset 必须和服务端一致否则中文乱码会在查询阶段出现而不会在连接阶段报错密码里的特殊字符建议直接写在 Form 的属性或配置文件中不要硬编码在按钮事件里。这个骨架跑通之后你基本就掌握了这套控件的核心用法。剩下的问题只有一个怎么把它干净利落地装进 Delphi 13.1。3. 安装 HeidiSQL-12.12-D123.zip 到 Delphi 13.1三个必改项安装一个第三方 Delphi 控件包本质上是让 IDE 能编译包工程然后把编译好的 BPL 注册进 IDE再把源码目录加进搜索路径。这套流程对任何控件包都适用HeidiSQL 也不例外。区别在于这个包的文件比较多安装前先检查目录结构能省掉后面一大半排查时间。3.1 解压后先认文件源码工程与预编译包的目录习惯拿到 zip 后不要急着全选解压到一个临时目录。先看一眼压缩包内部结构。常见做法是顶层有 src 和 bin 两个目录src 下面是 .dpk、.pas、.dfmbin 下面是编译好的 .bpl 和 .dcp另外会有 Readme.txt 或 InstallNotes.txt 说明依赖了哪些第三方库比如 SynEdit、ZCompression 等。如果你的 zip 里只有 .pas 没有 .dpk说明作者希望你把源码文件直接拷进自己的工程目录然后手动添加单元引用而不是走 IDE 包安装。这种旧式做法在 Delphi 社区里很常见优点是免去 BPL 管理缺点是项目和源码耦合太紧。D123 这个包名带了明确的编译目标我建议优先找 .dpk 走标准安装因为没有包的封装就别谈设计时控件。检查完目录结构后把整个目录拷贝到一个固定位置。注意路径不要带中文名和空格比如 D:\Components\HeidiSQL-12.12-D123 就比“桌面\控件包”稳妥。Delphi 的库路径对空格和中日韩字符支持不算好路径越简单后面的玄学问题越少。3.2 编译并安装包从 dpk 到 IDE 组件面板打开 Delphi 13.1用 File Open Project 找到 src 目录下的 .dpk 文件。如果目录里同时有设计时包和运行时包两个文件通常命名带 .design 后缀的是设计时包另一个是运行时包。安装顺序是先编译运行时包再编译设计时包。每个包的操作步骤一致在 Project Manager 里右键 dpk 工程选择 Build 编译编译通过后再次右键选择 Install。IDE 会弹出安装提示框显示“Package 安装成功”然后组件面板里会出现一个新增的页签。HeidiSQL 控件一般会落在名为 HeidiSQL 的面板页签中。对于预编译版如果你只想装 .bpl 而不重新编译源码可以通过 Component Install Packages 打开包管理器点 Add 按钮选择 bin 目录下的 .bpl 文件。IDE 会立即加载并显示包中的所有注册组件。这个方式快但前提是包作者已经用与你版本完全一致的 Delphi 编译过。如果编译时遇到错误最常见的两个原因分别是缺少依赖包和平台不匹配。缺少依赖包需要在 Tools Options Library Library Path 里加上依赖库路径平台不匹配则需要确认包工程的目标平台和当前 IDE 一致。Delphi 13.1 默认使用 Win32 还是 Win64 取决于工程配置建议先把包工程切到 Win32 编译一次因为绝大多数第三方控件的预编译产物都是 32 位。3.3 Library Path 与 Search Path装完找不到 DCP 的根源很多人装完控件后编译自己的项目时报“Unit HeidiQLib.Core not found”或者“HeidiSQL.dcp not found”。这不是包没装成功而是 Delphi 的搜索路径里没有包含 .dcp 和源文件所在目录。设计时包的安装和编译期解析是两个独立机制IDE 的安装包列表负责运行时加载而编译器的搜索路径负责编译时找单元。打开 Tools Options Delphi Options Library在 Library Path 里新增两个条目一个是源码目录一个是编译输出目录。源码目录让 IDE 能找到 .pas编译输出目录让 IDE 能找到 .dcp。如果你把包工程和你的主工程放在同一个目录组还可以在 Project Manager 的 Target 里加 Search Path 来约束范围。三个必改项总结如下第一把源码目录加进全局 Library Path第二把编译输出目录加进 Library Path 或放到已有 DCP 输出目录第三确认主工程和包工程的平台一致。这三项都做完后新开一个工程拖一个 THeidiSession 到 Form 上能放置就说明安装链路全部打通。注意不要在已经打开主工程时修改全局 Library Path改完路径后重开一下 IDE 或者至少关闭重开工程编译器的路径缓存有时不会立即刷新。3.4 命令行重编不打开 IDE 也能构建包如果你需要做持续集成或者团队其他成员需要复现同一套安装环境用 IDE 手动编译不是好方案。常见做法是用 MSBuild 命令行编译包工程。先通过 rsvars.bat 初始化环境变量再对 .dproj 执行构建。下面是以 Delphi 13.1 为例的标准命令call C:\Program Files\Embarcadero\Studio\版本目录\bin\rsvars.bat msbuild HeidiSQL123.dproj /p:ConfigRelease /p:PlatformWin32 /t:Build这个命令会读取 .dproj 里的编译选项生成 .bpl、.dcp 和 .res。Build 动作会把编译后的文件输出到 .dproj 中指定的 DCP 和 BPL 目录。如果你在 CI 上跑建议在命令后面加上 /v:minimal 减少日志量编译失败时再用 /v:detailed 查具体单元错误。命令行编译和 IDE 安装有一个重要区别命令行只负责编译产物不负责注册到 IDE。所以 CI 构建完成后还是要通过 Install Packages 指向生成的 .bpl或者让打包脚本把 .bpl 复制到 IDE 的默认包目录。多数团队的做法是让开发机各自手动安装CI 只验证源码能不能编过。4. 用 HeidiSQL 控件跑通第一个查询最小 Demo 与连接树安装只是开始真正考验控件包价值的是能不能在你的业务代码里跑起来。这一章给三个可直接抄的场景一个带参数的单表查询 Demo一个把数据库列表挂到 TreeView 的导航树一个多线程查询的封装模板。这三个场景覆盖了数据库工具类程序最常用的骨架。4.1 带参数查询与结果集读取跑通第一段业务代码很多人在第一次使用 THeidiQuery 时会直接拼 SQL但 HeidiSQL 这类成熟工具对参数化查询的支持是完善的。用参数而不是拼字符串第一能避开 SQL 注入第二能减少引号转义的麻烦。下面是一个带 WHERE 条件的最小示例procedure TForm1.BtnSearchClick(Sender: TObject); var LQuery: THeidiQuery; begin // 假设 FSession 已经在 Form 的 OnCreate 里连接好了 LQuery : FSession.NewQuery; try LQuery.SQL.Text : SELECT id, order_no, total_amount, status FROM orders WHERE status :pStatus AND total_amount :pMinAmount ORDER BY id DESC LIMIT 200; LQuery.ParamByName(pStatus).AsString : PAID; LQuery.ParamByName(pMinAmount).AsFloat : 100.0; LQuery.Open; // 遍历结果集同时演示字段取值方式 while not LQuery.Eof do begin ListView1.Items.Add( LQuery.FieldByName(order_no).AsString / LQuery.FieldByName(total_amount).AsString); LQuery.Next; end; finally LQuery.Free; end; end;这里的关键写法是 ParamByName。Delphi 的查询组件参数名和 SQL 里冒号开头的占位符一一对应参数对象必须先赋值再 Open否则会报“参数未绑定”的错误。FieldByName 返回的是字段对象AsString 和 AsFloat 负责按类型取值。参数类型尽量显式设置。如果数据库字段是 decimal你必须在 Params 里先创建参数并 Setting AsFloat而不是直接传字符串。HeidiSQL 的底层连接会按参数类型做显式转换参数类型不匹配时不会在 SQL 层报错而是会在读取结果集时出现精度变化。4.2 用连接树把库表挂进 TreeView树形导航的实现数据库工具必然要有一个树形导航左边显示服务器、库、表三层结构。常见做法不是让 THeidiSession 直接返回一个树控件而是用它的元数据方法拉取数据库名和表名然后自己填充 TreeView。这样你有完全的控制权比如按权限过滤库名或者给表节点追加统计信息。下面演示一个懒加载版本加载时只填充数据库列表点击数据库节点时才去查询表名。这个做法对表数量很多的生产库很友好避免一次拉全量元数据把界面卡死。procedure TMainForm.LoadServerTree(ATree: TTreeView); var LRoot, LDbNode: TTreeNode; LDatabases: TStrings; I: Integer; begin ATree.Items.Clear; LRoot : ATree.Items.Add(nil, FSession.Hostname); LRoot.ImageIndex : 0; // 拉取数据库名列表 LDatabases : FSession.ListDatabases; try for I : 0 to LDatabases.Count - 1 do begin LDbNode : ATree.Items.AddChild(LRoot, LDatabases[I]); LDbNode.ImageIndex : 1; // 先不加载表点击节点时再懒加载 LDbNode.HasChildren : True; end; finally LDatabases.Free; end; end; procedure TMainForm.TreeDbExpanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean); var LTables: TStrings; I: Integer; begin AllowExpansion : True; if Node.HasChildren and (Node.Count 0) then begin LTables : FSession.ListTables(Node.Text); try for I : 0 to LTables.Count - 1 do begin Node.Owner.AddChild(Node, LTables[I]); end; finally LTables.Free; end; end; end;这段代码有几个细节。HasChildren 设为 True 后TreeView 会在节点前显示展开箭头从而触发 OnExpanding 事件Node.Count 0 的判断用来防止重复加载。ListTables 返回的是表名字符串列表个别数据库类型下还会包含视图名如果你的业务需要区分表和视图需要用单独的元数据接口去查这个看控件包的具体实现。连接树做好以后双击表节点跳到数据网格是数据库工具的标配。你可以把表名传给 THeidiQuery 生成一个不带条件的查询也可以直接调用 Session 的快捷方法生成表数据。这个交互的代码量不大但是非常提升工具的整体质感。4.3 多线程查询连接不能在线程间共享一次一个 Session如果你在一个桌面程序里运行耗时 SQL界面会假死这在处理百万行数据时尤其明显。Delphi 多线程的原则很简单把查询丢到 TThread 里查询完成后通过 Synchronize 回传到主线程。但多线程查询有几个细节一旦踩中就是血泪经验。最常见的错误是让多个线程共享同一个 THeidiSession 实例。THeidiSession 内部持有连接句柄而连接句柄不是线程安全的两个线程同时执行 SQL 会导致读取结果错乱甚至异常。正确做法是每个线程创建独立的 Session线程结束时自动释放。下面是一个封装好的线程骨架type TQueryThread class(TThread) private FHost, FUser, FPassword, FSQL: string; FResult: TStringList; protected procedure Execute; override; procedure SyncComplete; public constructor Create(AHost, AUser, APassword, ASQL: string); destructor Destroy; override; end; constructor TQueryThread.Create(AHost, AUser, APassword, ASQL: string); begin inherited Create(False); FHost : AHost; FUser : AUser; FPassword : APassword; FSQL : ASQL; FResult : TStringList.Create; end; destructor TQueryThread.Destroy; begin FResult.Free; inherited Destroy; end; procedure TQueryThread.Execute; var LSession: THeidiSession; LQuery: THeidiQuery; begin // 注意每个线程独立创建连接 LSession : THeidiSession.Create(nil); try LSession.Hostname : FHost; LSession.Username : FUser; LSession.Password : FPassword; LSession.ConnectorType : ctMySQL; LSession.Connect; LQuery : LSession.NewQuery; try LQuery.SQL.Text : FSQL; LQuery.Open; while not LQuery.Eof do begin FResult.Add(LQuery.FieldByName(id).AsString); LQuery.Next; end; finally LQuery.Free; end; finally LSession.Free; end; if not Terminated then Synchronize(SyncComplete); end; procedure TQueryThread.SyncComplete; begin // 在主线程中把结果刷新到 UI ListBox1.Items.Assign(FResult); Label1.Caption : 共 FResult.Count.ToString 条; end;这个模板解决的是“查询执行和 UI 展示”的分离。Execute 里做的全是耗时操作Synchronize 确保 UI 更新在主线程执行。连接释放放在 finally 里即使 SQL 执行抛异常也能保证 Session 不泄漏。这里有一个容易翻车的点TThread 使用 Synchronize 时不要在 Execute 里直接访问主线程的 VCL 控件应该通过 FResult 传递数据在 SyncComplete 里统一刷新。Delphi 的 Synchronize 机制是排队执行的如果主线程正在处理别的消息你的 UI 回传会延迟这是正常行为。如果你还要在查询线程里访问剪贴板或者 COM 对象建议在 Execute 开头调用 CoInitializeEx(nil, COINIT_MULTITHREADED)。这不是 HeidiSQL 控件的要求而是你后续扩展导出功能时避免 COM 初始化缺失的防御性写法。5. HeidiSQL 控件避坑指南5 条现象、原因、处理控件包安装本身不复杂但真正跑业务代码时客户端库、字符集、平台位宽这些问题会轮番出现。这一章把最常见的 5 个坑按“现象 → 原因 → 处理”写清楚可以直接对照排查。5.1 运行时报“libmysql.dll 找不到”现象程序编译通过但点击连接按钮时弹出“Can’t load library: libmysql.dll”或“找不到指定的模块”。原因THeidiSession 只封装了连接逻辑真正和 MySQL 服务端通信的是 MySQL 官方客户端库 libmysql.dll或者 MariaDB 的 libmariadb.dll。这个 DLL 不在控件包里需要你随程序一起分发。系统 PATH 里没有程序目录里也没有就会报这个错。处理把对应客户端库拷贝到可执行文件同目录或者用 THeidiSession 提供的 ClientLibrary 属性指定全路径。生产环境建议把 DLL 放在 exe 同目录而不是系统目录避免用户机器环境差异。MySQL 5.7 和 8.0 的 libmysql.dll 不完全兼容连接时注意服务端版本配套。5.2 表格中文乱码字符集没有随连接上送现象SQL 查询英文正常中文返回问号“???”或者写入数据库的中文变成乱码。连接参数里明明设置了 UTF-8界面却仍然乱。原因字符集协商发生在连接握手阶段。如果你只改了客户端显示编码没有告诉服务端这次连接使用 utf8mb4服务端会按默认字符集返回数据。HeidiSQL 控件里的 Charset 参数就是干这个用的但往往被漏掉。处理连接前设置 LSession.Charset : utf8mb4重新连接后再测试。如果使用的是 MariaDB注意 utf8mb4 和 utf8 的差别不要用旧的 utf8 别名。库表本身的字符集也要确认客户端连接字符串和服务端表字符集三层都要一致缺一层都会乱码。5.3 编译提示“HeidiSQL.dcp not found”但明明装过现象新建工程后引用 HeidiQLib 单元编译时报“Unit HeidiQLib.Core was not found”或者“HeidiSQL.dcp not found”。回 IDE 看安装包列表BPL 确实加载了。原因IDE 的安装包注册和编译器的单元搜索路径是两套系统。BPL 加载只代表设计时组件可用不代表编译器能找到 .dcp 和 .pas。全局 Library Path 没有加入源码目录编译时自然找不到。处理按 3.3 的步骤在 Library Path 中追加源码目录和 DCP 输出目录然后重启 IDE。用“RELEASE”配置重新构建一次包工程确保 DCP 被重新生成到指定位置。5.4 64 位目标平台下设计时正常、运行时访问冲突现象包安装成功组件能在 Form 上放置程序设置 Win64 平台也能编译但运行后点击按钮访问 Session 的属性时抛出 Access Violation。原因你安装的 BPL 是 Win32 的而主工程编译成 Win64。Delphi 的 IDE 本身是 32 位进程设计时用的是 32 位包但运行时你的程序是 64 位加载的却是同一套源码在 64 位下重新编译的产物。如果 .dproj 没配置 64 位构建或者源码里有汇编/指针宽度相关的代码就会在运行时爆发。处理用 MSBuild 对 .dproj 执行 Win64 构建生成 64 位 BPL。如果包工程本身不支持 64 位那就把主工程定为 Win32。HeidiSQL 控件大部分代码是纯 Delphi 实现64 位兼容问题不大但预编译包未必带 64 位版本。5.5 卸载旧版本 BPL 后 IDE 启动报找不到模块现象卸载旧版控件或从别处复制了一个新版 BPL 覆盖后Delphi 启动弹出错误提示“Cannot load package C:...\HeidiSQL_Old.bpl. The specified module could not be found.”。原因旧的 BPL 文件被删除或换名但注册表里的包记录仍然指向它。IDE 启动时按注册表记录加载全部包找不到文件就会报错。这个情况经常出现在用压缩包直接覆盖安装的场景。处理用 Component Install Packages 打开包管理器找到对应包条目点击 Remove 删除注册记录。如果不再需要旧包直接移除即可如果需要新包先移除旧的再添加新版 BPL。不要手动改注册表IDE 的包管理器已经足够处理这种情况。6. 结果集导出 CSV 与三步验证收尾技巧和验收方法控件装好、跑通、能查数据之后真正让工具类程序“完整”的常是导出功能。这里给出一个基于 THeidiGrid 的 CSV 导出方案以及一套安装后的验收清单。导出功能看起来简单但字段转义和编码是翻车高发区。6.1 用 THeidiGrid 把查询结果导出到 CSV如果查询结果已经绑定到 THeidiGrid可以直接调用网格自带的保存方法procedure TForm1.BtnExportCsvClick(Sender: TObject); var LSaveDlg: TSaveDialog; begin LSaveDlg : TSaveDialog.Create(nil); try LSaveDlg.Filter : CSV 文件|*.csv; LSaveDlg.DefaultExt : .csv; if LSaveDlg.Execute then begin // SaveToFile 内部会处理字段分隔符和引号转义 HeidiGrid1.SaveToFile(LSaveDlg.FileName); end; finally LSaveDlg.Free; end; end;如果控件没有提供 SaveToFile可以自己遍历 Query 的结果集写文本文件。要点是每个字段写完后追加逗号字段值里包含逗号、引号、换行的要加双引号包裹文件开头写入 UTF-8 BOM 防止 Excel 打开中文乱码。导出大量数据时不要用 String 拼接改用 TStringList 逐行写入再由它一次性保存性能差距在万行以上场景非常明显。6.2 装完不自检三步验收方法安装完控件包先别急着写业务代码花两分钟做一个最小化验收能省掉后面大量的定位工作。检查项操作通过标准设计时可用性新建 VCL 工程从组件面板拖一个 THeidiSession 到 Form能放置属性窗口不报错编译期依赖写最小连接代码编译整个工程不出现“HeidiSQL.dcp not found”运行时联通性用一个测试连接串跑一次 SELECT 1返回结果字符集不乱码这套验收方法背后的逻辑是“分层确认”。设计时没问题代表 BPL 安装正确编译没问题代表 DCP 路径正确运行时没问题代表客户端 DLL 和连接参数正确。三个环节各自独立任何一层失败都能快速缩小范围。我自己的习惯是每次换 Delphi 大版本时都先拿这个控件包的 D 构建号和新版编译器做一次兼容性验证再决定要不要升级主工程。第三方控件的版本对齐是玄学但多花十分钟验证总好过项目做到一半再翻车。希望这一篇能帮你在 Delphi 13.1 里把 HeidiSQL 控件顺利用起来少走点弯路。本文还有配套的精品资源点击获取