You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

系统存在Jet.OleDb驱动却抛出“无法识别数据库格式”异常的原因?

问题解答

1. 为什么Jet.OleDb驱动存在但connection.Open()仍抛出异常?

没错,Microsoft.Jet.OLEDB.4.0驱动完全不支持.accdb格式*。这个驱动是为旧版Access数据库(.mdb格式,Access 2003及更早)设计的,而.accdb是Access 2007及以后版本引入的新格式,需要使用专门的ACE驱动(Microsoft.ACE.OLEDB.12.0或更高版本)来处理。

你安装了Microsoft Access 2013 Runtime但没修改连接字符串,代码依然在尝试用Jet驱动连接accdb文件,自然会抛出Unrecognized database format异常——这是Jet驱动明确告知你它无法识别这个新格式。

另外补充一点:Jet驱动没有64位版本,所以在64位Windows系统的64位运行时中,尝试使用Microsoft.Jet.OLEDB.4.0会直接触发InvalidOperationException(找不到提供者),而32位运行时中Jet驱动存在,但处理不了accdb,所以抛出OleDbException,这和你观察到的现象完全一致。

2. 为什么OleDbEnumerator.GetElements()会返回Jet驱动,而非直接抛出ProviderNotFound异常?

OleDbEnumerator.GetElements()的作用是枚举系统中已注册的所有OLE DB提供者,它只检查注册表中是否有对应的驱动注册项,不会验证该驱动是否能处理你指定的数据库格式,也不会提前判断驱动和当前进程位数是否兼容。

Jet驱动在32位Windows系统中是默认注册的,在64位Windows系统的32位兼容注册表分支中也会存在注册信息,所以枚举器会把它列出来。只有当你实际尝试用这个驱动连接不兼容的格式,或者在不支持的位数环境中加载它时,才会抛出对应的异常。

解决方案

要解决这个问题,你需要做两件事:

  • 替换连接字符串中的驱动为ACE驱动,比如:
    string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\.\my.accdb";
    
    如果你安装的是Access 2016或更高版本的Runtime,也可以用Microsoft.ACE.OLEDB.16.0
  • 确保运行时位数和ACE驱动位数一致:如果你的代码编译为x86,就安装32位的Access Runtime;如果是x64编译,就安装64位的Runtime,避免出现找不到提供者的异常。

内容的提问来源于stack exchange,提问作者broadband

火山引擎 最新活动