无拖拽控件时FireDAC加载Access数据到DBGrid及DLL开发咨询
问题诊断&代码修复
你的代码存在4类核心错误
- 对象创建语法错误:类实例化的语法写错了,你当前的写法是对未初始化的指针调用构造方法,直接触发内存访问错误:
错误写法:driver.Create(nil);/src.Create(nil);
正确写法:driver := TFDPhysMSAccessDriverLink.Create(nil);/src := TDataSource.Create(nil); - 资源生命周期逻辑错误:你在点击事件的finally块里直接释放了
qry、cnn,而DBGrid绑定的DataSource依赖这两个对象存活,事件执行完对象就被销毁了,界面自然无法显示数据,还会触发访问异常。 - 驱动配置错误:使用
TFDPhysMSAccessDriverLink时不需要手动指定ODBC驱动名和DriverID为ODBC,FireDAC已经封装好了Access的适配逻辑,错误的配置会导致连接失败。 - 路径问题:你用相对路径
data.mdb,需要确保该文件和你生成的exe在同一个目录,否则会提示找不到数据库文件,调试阶段建议先写绝对路径验证。
FireDAC工作原理说明
FireDAC是Embarcadero推出的通用数据访问框架,核心分层逻辑如下:
- 驱动层:对应你用到的
TFDPhysMSAccessDriverLink这类驱动链接组件,负责对接不同数据库的原生驱动/ODBC驱动,屏蔽不同数据库的底层访问差异,你不需要手动操作ODBC接口,FireDAC会自动调用。 - 连接层:对应
TFDConnection,负责管理和数据库的物理连接,维护连接池、事务、连接参数配置,所有数据集组件都要绑定到一个连接实例上才能执行SQL。 - 数据集层:对应
TFDQuery、TFDTable这类组件,负责把SQL语句发送到数据库执行,把返回的结果集缓存到内存中,支持导航、编辑、筛选等操作。 - 数据适配层:对应
TDataSource,是数据集和UI数据感知控件(比如DBGrid)之间的桥梁,负责把数据集的变更同步到UI,把UI的编辑操作同步回数据集。
修正后的可运行代码
建议把cnn、qry、driver、src改成窗体的成员变量,不要用局部变量,在窗体销毁的时候再释放,避免资源提前释放导致的绑定失效:
// 首先把下面四个变量定义到TForm1的类成员的private区域 private cnn : TFDConnection; qry : TFDQuery; src : TDataSource; driver : TFDPhysMSAccessDriverLink; // 按钮点击事件的实现 procedure TForm1.btnLoadAccessClick(Sender: TObject); begin // 先释放之前可能存在的实例,避免重复创建 FreeAndNil(cnn); FreeAndNil(qry); FreeAndNil(src); FreeAndNil(driver); // 实例化Access驱动 driver := TFDPhysMSAccessDriverLink.Create(nil); // 兼容mdb和accdb格式,如果是32位系统也可以填你之前写的Microsoft Access Driver (*.mdb) driver.VendorLib := 'ACEODBC.DLL'; // 实例化数据库连接 cnn := TFDConnection.Create(nil); try cnn.Params.DriverID := 'MSAcc'; // 直接用FireDAC封装的Access驱动ID,不需要写ODBC cnn.Params.Database := 'C:\完整路径\data.mdb'; // 先写绝对路径测试没问题再改相对路径 cnn.Params.Add('LoginPrompt=False'); // 禁用登录弹窗 cnn.Connected := True; // 实例化查询组件执行SQL qry := TFDQuery.Create(nil); qry.Connection := cnn; qry.SQL.Text := 'select * From Staff'; qry.Open; // Open方法已经自动激活数据集,不需要额外写Active:=True // 绑定数据源到DBGrid src := TDataSource.Create(nil); src.DataSet := qry; DBGrid1.DataSource := src; except // 出错时释放资源避免内存泄漏 FreeAndNil(cnn); FreeAndNil(qry); FreeAndNil(src); FreeAndNil(driver); raise; // 抛出异常方便定位具体错误 end; end; // 窗体销毁时统一释放资源 procedure TForm1.FormDestroy(Sender: TObject); begin FreeAndNil(src); FreeAndNil(qry); FreeAndNil(cnn); FreeAndNil(driver); end;
额外注意事项
- 如果你要打包成DLL,不要把DBGrid的UI引用放到DLL里,DLL只负责提供数据访问接口返回数据集,UI绑定逻辑放在主程序中,避免VCL跨模块的兼容性问题。
- 64位程序需要安装64位Access ODBC驱动,32位程序对应32位驱动,否则会提示找不到驱动。
内容的提问来源于stack exchange,提问作者minhtungph
相关产品推荐
相关产品推荐

