
简介面向仍在使用 Delphi 7 与 dbExpress 访问 MySQL 5.7 的开发者这份压缩包提供经过项目实测的 libmysql.dll、dbxopenmysql50.dll 两个关键动态库及配套连接示例重点解决网上版本杂乱、下载后难以正常连通数据库的问题。包内共 17 个文件整体约 1.3MB包含 dll 动态库、pas 与 dpr 源码、dfm 窗体、sql 脚本、dcu 编译单元、exe 演示程序以及 docx 配置说明等既覆盖 TSQLConnection 可视化配置过程也保留了可直接运行的测试工程。示例还专门演示如何区分数据库字段为 NULL 还是空字符串并验证程序在 Windows XP 与 Windows 10 下的运行情况发布时只需携带 libmysql、dbxopenmysql50 等三个运行库即可。包内另附 SQL 建表脚本与窗体设计文件便于对照阅读源码结构、复现连接过程也能作为二次开发的基础工程。已有 827 人学习下载适合需要快速排查 Delphi 连接 MySQL 5.7 环境配置、动态库匹配与字段判空问题以及处理旧版本兼容性调试的开发者参考。1. 一个下午踩两次坑Delphi 连 MySQL 5.7 到底缺哪两个文件上周帮人收拾一台要重装的上位机。程序是早年用 Delphi 写的数据库迁到了 MySQL 5.7程序拷过去一点开就弹框Unable to load dbxopenmysql50.dll (error code 126)。把 dll 找齐塞进去报错换成了Cannot load vendor library [libmysql.dll]。两个文件、两个报错来回折腾了一下午。这套组合在维护老项目的圈子里太常见了Delphi 的 dbExpress 本身不认识 MySQL得靠额外的驱动 dlldbxopenmysql50.dll去桥接 MySQL 的客户端库libmysql.dll两个文件都不在安装包里得单独凑。位数、版本、目录三样有一样对不上程序就是起不来。这篇按我自己重装环境的顺序写先对版本再放文件再填参数最后验证——照着走能省掉那个下午。2. 装前对齐版本Delphi 位数、MySQL 5.7 和两个 dll 的匹配动手拷文件之前有三件事必须先确认清楚宿主进程是几位、驱动 dll 是几位、客户端库是几位。这三者错一个后面所有配置都是白费。2.1 先确定 exe 是 32 位还是 64 位dbExpress 是进程内加载 dlldll 的位数必须和宿主进程完全一致跟操作系统是几位没有关系。64 位的 Windows 上跑一个 32 位的 Delphi 程序它要的是 32 位的 libmysql.dll你给它一个 64 位的加载阶段就直接失败。判断方法有好几种我习惯用dumpbin看 PE 头# 在 VS 开发者命令提示符里执行或把 dumpbin 所在目录加进 PATH dumpbin /headers YourApp.exe | findstr /i machine # machine (x86) - 32 位进程必须配 32 位的 libmysql.dll 和 dbxopenmysql50.dll # machine (x64) - 64 位进程两个 dll 都要换 64 位版本/headers读的是 PE 文件头findstr只筛出机器类型那一行输出干净。机器上没有 Visual Studio 的话任务管理器里看进程名后面有没有(32 位)标记或者用 Process Explorer 看进程属性里的 Image 类型结论一样。提示判断依据永远是宿主进程的位数不是服务器。MySQL 服务端装的是 64 位版本你的 32 位客户端程序照样只能用 32 位的 libmysql.dll这两件事互不影响。2.2 dbxopenmysql50.dll 在这条链路的什么位置把调用链摊开看缺文件时报错为什么会变来变去就清楚了TSQLConnection→ dbExpress 核心 →dbxopenmysql50.dll→libmysql.dll→ TCP 3306 → mysqldDelphi 自带的 dbExpress 只覆盖少数几种数据库MySQL 不在其中。dbxopenmysql50.dll就是补上的这一层驱动它把 dbExpress 定义的接口翻译成 libmysql 的 C API 调用。libmysql.dll则是 MySQL 官方客户端库负责真正的协议握手和数据收发。所以两个文件缺一不可缺的位置不同报错也不同少了驱动 dllDelphi 在DriverName这一层就找不到对应的驱动报的是Unable to load dbxopenmysql50.dll驱动加载成功但客户端库没到位报的是Cannot load vendor library。看到哪一句就知道该查哪一层不用瞎猜。至于文件名里的50通常理解成它对着某一代客户端库接口做的适配。实际以随包说明为准别拿它去硬配 MySQL 8.0 的 libmysql.dll认证插件那一关过不去。2.3 两个 dll 与运行环境的匹配对照运行场景宿主进程libmysql.dlldbxopenmysql50.dll说明老项目默认编译32 位5.7 系列 x86 版32 位最常见两个都是 32 位新工程改过目标平台64 位5.7 系列 x64 版64 位两个必须同时换不能一 32 一 64同一台机器跑两套程序混合分目录各放一份分目录各放一份别往系统目录里塞会互相踩服务端升到 8.032 位仍建议用 5.7 的库32 位账号认证插件要改成服务端兼容的那一种表格里最后一行是血泪经验服务端升到 8.0 之后账号默认的认证方式变了5.7 那一代的客户端库不认识新的握手包表现是连接直接断开、错误信息还很含糊。要么把该账号的认证方式改回 5.7 认识的那一种要么整套客户端库和驱动一起升级——后者在老项目里通常动不了只能走前者。2.4 落地目录怎么摆确定好位数把两个文件和程序放成这个结构这是最省事、也最好排查的一种D:\App\ ├─ YourApp.exe ├─ libmysql.dll ├─ dbxopenmysql50.dll ├─ dbxdrivers.ini 可选运行期读取 └─ dbxconnections.ini 可选运行期读取放 exe 同目录有两个好处。一是加载优先级Windows 在默认搜索模式下会先看 exe 所在目录再往系统目录走程序一定能找到自己那一份二是不污染系统换版本时删掉重拷就行不用去System32里翻。dbxdrivers.ini和dbxconnections.ini不是必须的。如果你的代码里是运行时给Params赋值这两个文件可以直接不放只有用设计期的连接编辑器、或者希望不同机器改配置不改代码时才需要它们写法在第 4 章。3. 放置与依赖补齐让进程真的能找到这两个文件文件拷过去了还是报 126八成不是位置问题而是依赖没齐或者拷错了版本。这一章按「放哪 → 缺什么 → 怎么盯」的顺序走一遍。3.1 首选方案跟 exe 放一起大部分情况下把两个 dll 复制到 exe 同目录就结束了。这一步没什么技术含量但有两个细节经常被忽略。第一个是覆盖问题。目标机器上可能已经有一份旧版本的 libmysql.dll 躺在同目录里复制的时候提示「是否替换」顺手点了否程序跑的其实还是旧的。安装前先看一眼目标目录里有没有同名文件有就先改名备份再拷。第二个是只读目录。程序装在Program Files下面的时候普通用户没有写权限直接拷文件会失败或者被重定向到虚拟存储。这种场景要么用管理员权限装一次要么把程序整个目录搬到D:\这种不需要提权的位置——后者我更推荐老项目的安装包经常没处理好权限。3.2 系统目录方案什么时候才用代价是什么把 dll 丢进C:\Windows\System3264 位系统上 32 位程序读的是C:\Windows\SysWOW64也能跑但我不建议除非你确实有多个程序要共用同一份客户端库。代价有三个。一是版本冲突另一套程序可能要 8.0 的库覆盖掉之后你这边又崩了而且崩得莫名其妙。二是排查困难出问题时很少有人第一时间想到去系统目录翻 dll。三是卸载不干净删了程序目录系统目录里那两份还留着下次装又撞上。真要走这条路务必记住 32 位程序读的是SysWOW64而不是System32这两个目录名字和实际含义是反的我第一次配的时候就栽在这里。3.3 error 126 的另一半原因libmysql.dll 自己还缺依赖error code 126的字面意思是「找不到指定的模块」但它不一定指你缺 libmysql.dll也可能是 libmysql.dll 缺它自己的依赖。MySQL 5.7 的 Windows 客户端库是 VC 2013 那一代工具链编出来的机器上没装对应的运行库加载一样失败。# 看 libmysql.dll 自己依赖哪些运行时库 dumpbin /dependents libmysql.dll # 常见会看到 MSVCR120.dll、KERNEL32.dll、WS2_32.dll 之类 # 如果 MSVCR120.dll 在任何目录下都搜不到就是运行库没装看到MSVCR120.dll缺失装一遍对应的 VC 运行库即可这一步在客户机上部署时尤其容易漏。程序在你开发机上好好的拷到客户机就报 126九成是这个原因。注意运行库要装和 dll 位数一致的那一版。32 位的 libmysql.dll 配 32 位的运行库装成 64 位的等于没装报错一模一样。3.4 用工具盯住加载过程它到底在找哪个路径猜不出来的时候别猜直接看。Process Monitor 加一个过滤器Process Name is YourApp.exe再加一条Path contains libmysql然后启动程序看输出里标着NAME NOT FOUND的行。那些行就是进程依次尝试过的路径从上往下看最后一条SUCCESS就是它实际加载的位置。如果所有尝试都是NOT FOUND说明文件确实没在搜索路径里如果SUCCESS指向了一个你没预期的目录比如系统目录里的旧版问题就变成了版本冲突。这一步花五分钟能省掉一小时的瞎试。我现在遇到加载类问题基本都先挂上这个过滤器看一眼就清楚了。4. 配置 TSQLConnectiondbxopenmysql50 的参数怎么填才生效文件到位只是让程序能加载驱动真正连上库还得把TSQLConnection的参数配对。这一章分三块驱动怎么登记、连接参数怎么给、哪些参数值得调。4.1 驱动登记dbxdrivers.ini 里要有这一段dbExpress 靠一张驱动表来找驱动 dll这张表存在dbxdrivers.ini里。设计期用的那份一般在 Delphi 安装目录的bin下运行期读的是 exe 同目录或者用户配置目录下的那一份。不管用哪份内容长这样[Installed Drivers] DbxOpenMySQL501 [DbxOpenMySQL50] GetDriverFuncgetSQLDriverMYSQL50 LibraryNamedbxopenmysql50.dll VendorLiblibmysql.dll LibraryNameExpdbxopenmysql50.dll VendorLibExplibmysql.dll BlobSize-1[Installed Drivers]这一段是注册表DbxOpenMySQL501里的 1 表示启用改成 0 就等于把这个驱动关掉有时排查「驱动到底有没有被识别」会用到。[DbxOpenMySQL50]是驱动自己的配置段段名就是后面DriverName要填的值。GetDriverFunc是驱动 dll 导出的工厂函数名写错了会报找不到入口点而不是找不到模块错误信息完全不同别搞混。LibraryName和VendorLib分别指向驱动 dll 和客户端库两个都填文件名、不写路径让系统按搜索顺序去找。LibraryNameExp和VendorLibExp是给「显式指定库」的写法留的口子通常和上面两行一致就行。4.2 连接参数两种给法选一种设计期给参数就是在dbxconnections.ini里加一段[erp_mysql] DriverNameDbxOpenMySQL50 HostName127.0.0.1 Databaseerpdb User_Nameerp Passworderp_pwd BlobSize-1 Chartsetutf8段名erp_mysql就是后面ConnectionName要填的值。这种写法的好处是换机器只改 ini 不动代码适合交付给运维同事维护的项目。运行时给参数更可控也是我现在更常用的方式var Conn: TSQLConnection; begin Conn : TSQLConnection.Create(nil); try Conn.DriverName : DbxOpenMySQL50; // 与 dbxdrivers.ini 的段名严格一致 Conn.LibraryName : dbxopenmysql50.dll; // 驱动 dll按文件名给别写绝对路径 Conn.VendorLib : libmysql.dll; // 客户端库 Conn.GetDriverFunc : getSQLDriverMYSQL50; // 驱动导出的工厂函数 Conn.LoginPrompt : False; // 关掉登录框参数不对时直接抛异常 Conn.Params.Clear; Conn.Params.Add(HostName127.0.0.1); // 用 IP别用主机名省掉一次 DNS 解析 Conn.Params.Add(Databaseerpdb); Conn.Params.Add(User_Nameerp); Conn.Params.Add(Passworderp_pwd); Conn.Params.Add(Chartsetutf8); // 注意拼写见 4.3 Conn.Params.Add(BlobSize-1); // -1 表示按需分配 Conn.Connected : True; // 到这一步才真正发起连接 finally // Conn 的生命周期自己管别在这里 Free 掉 end; end;几个参数值得单独说。LoginPrompt : False一定要设否则参数错了会先弹一个登录框掩盖掉真正的错误信息排查时非常误导人。HostName用 IP 而不是机器名是为了绕开主机名解析某些内网环境下解析超时会把连接卡住十几秒。Connected : True才是真正建立连接的动作前面所有赋值都只是准备。LibraryName和VendorLib写相对文件名就行。写绝对路径的话换一台机器路径变了又得改代码反而更麻烦。4.3 参数取舍字符集、BlobSize、超时参数建议值作用与取舍Chartsetutf8或utf8mb4客户端字符集拼写就是少个 a按驱动实际拼写填BlobSize-1按需分配缓冲写固定值会让大字段截断Compress按网络情况内网没必要开跨机房可以试CPU 换带宽ConnectTimeout10左右有的驱动版本根本不认这个键写了不生效也不报错字符集这里有个反复出现的坑参数名的拼写。按标准写法应该是Charset但这一代驱动里写的是Chartset少一个 a。填错的时候不会报错只是不生效然后你就看到中文变成问号还以为是数据库那边的问题。我的做法是照驱动实际支持的拼写填改完立刻用一条中文数据验证不要等到上线。选utf8还是utf8mb4取决于表里有没有 emoji 或者生僻字。MySQL 5.7 的utf8实际是三个字节的版本四字节字符存不进去。有这类数据就必须上utf8mb4同时服务端和表也要一起改光改客户端参数没用。BlobSize写-1是省心的做法。写死一个数值比如 4096超过的字段会被静默截断取出来是半截数据这种 bug 最难查因为不报任何错。超时类参数要有心理准备不是每个驱动版本都支持写了不生效也不会提示。真正的兜底还是在业务层加超时控制别指望驱动参数。5. 避坑清单六条反复出现的报错和它们的成因下面这六条是我在不同机器上真的踩过的按现象、原因、解决三段写遇到同款直接对照。5.1 启动就报 error code 126现象程序一启动或者第一次Connected : True时弹Unable to load dbxopenmysql50.dll (error code 126)。原因三种可能——文件没在搜索路径里、文件位数不对、文件自身缺依赖。第三种最容易被忽略。解决先用dumpbin /dependents分别看两个 dll 的依赖列表缺MSVCR120.dll就装运行库依赖齐了就确认 exe 同目录下确实有这两个文件、位数和进程一致。挂 Process Monitor 看NAME NOT FOUND的路径能直接定位它找的是哪。5.2 报 error code 193现象报错信息里带error code 193或者直接提示「不是有效的 Win32 应用程序」。原因位数不匹配。32 位进程加载了 64 位的 dll或者反过来。这个错比 126 更明确说明文件找到了就是版本不对。解决按第 2.1 节确认宿主进程位数把两个 dll 一起换成对应位数。注意两个要同时换只换一个的话报错会从 193 变成别的容易误以为没修好。5.3 连接成功中文全是问号现象Connected正常查询也返回数据就是中文显示成???英文和数字都正常。原因客户端字符集没生效。要么参数名拼错Chartset写成了Charset要么填的值和服务端、表的字符集对不上。解决先确认参数名拼写和驱动要求一致再执行SHOW VARIABLES LIKE character_set_%看服务端各层字符集。表是utf8mb4而客户端给utf8的情况很常见四字节字符照样丢。改完用一条确定含中文的记录验证别看英文数据。5.4 拿 8.0 的客户端库配 5.7 的服务端现象连上去立刻断开错误信息含糊说认证失败但密码明明是对的。原因MySQL 8.0 默认的账号认证方式和 5.7 不一样5.7 那一代的 libmysql.dll 不认识新的握手流程。解决保持客户端库和服务端大版本一致5.7 的服务端就用 5.7 的 libmysql.dll。服务端已经升到 8.0 的把业务账号的认证方式改成 5.7 认识的那一种别去动驱动。5.5 设计期能连编译出来连不上现象在 IDE 里点测试连接一切正常编译出的 exe 跑起来就报加载失败。原因设计期用的是 Delphi 安装目录下那份dbxdrivers.ini和那套 dll编译出的程序读的是 exe 同目录的配置。两边环境不一样。解决把dbxdrivers.ini、dbxconnections.ini和两个 dll 都复制到输出目录或者干脆全部改成运行时赋值不依赖 ini。我现在新写的代码一律运行时给参数就是为了避开这个差异。5.6 本机正常拷到客户机就崩现象开发机上跑了一周没问题打包发到客户机一启动就报 126。原因客户机缺 VC 运行库或者装过别的软件系统目录里有一份版本不对的 libmysql.dll 被优先加载了。解决安装包里带上运行库两个 dll 固定放 exe 同目录别依赖系统目录。交付前在干净的机器上跑一遍第 6 章的三步验证不要拿开发机当验收环境。6. 装完怎么验证三步确认连接真的跑通文件放好、参数填完很多人到这一步就收工了结果交付之后才发现是「能连上但用不了」。我现在的习惯是走完三步再算装完。第一步先撇开 Delphi用命令行确认账号和服务端没问题。mysql -h 127.0.0.1 -P 3306 -u erp -p -e select version(), character_set_server, default_authentication_plugin;这条命令一次看三件事服务端版本是不是 5.7、服务端默认字符集是什么、默认认证方式是哪一种。如果这一步就失败那问题在账号权限或者网络跟两个 dll 一点关系没有别在客户端上浪费时间。第二步写一个最小的 Delphi 程序只放一个TSQLConnection和一个TSQLQuery。Query.SQL.Text : select version() as v, character_set_connection as cs; Query.Open; Memo1.Lines.Add(Query.FieldByName(v).AsString); // 期望看到 5.7.x Memo1.Lines.Add(Query.FieldByName(cs).AsString); // 期望和客户端字符集一致 Query.Close;这一步能过说明驱动加载、客户端库加载、协议握手、字符集协商四关全通了。character_set_connection的值和你填的字符集参数对不上就是第 4.3 节那个拼写问题。第三步用真实数据类型走一遍别只查select 1。验证项做法通过标准中文插入一条含中文的记录再读回读回内容与写入一致大字段写入超过 64KB 的文本或二进制读回长度一致无截断事务StartTransaction后插入再Rollback表里没有新增记录重连断开后重新Connected : True能正常重连不报错大字段那一项专门用来验证BlobSize-1有没有生效。事务那一项验证的是驱动对事务的支持程度某些版本在自动提交上的行为和预期不一样回滚不掉就很麻烦。这三步加起来不到二十分钟但能把后面交付阶段八成的返工挡掉。从那以后我每次换机器部署这套环境都强制先走一遍这三步再谈业务功能——「程序能打开」和「数据库真的通了」是两回事中间隔着的正是那两个 dll 和一堆参数。希望帮到你。本文还有配套的精品资源点击获取