Access使用TableDefs添加MySQL链接表报Error 3191故障排查
Access链接MySQL表触发Error 3191:Cannot define field more than once
问题描述
- 操作场景:通过VBA调用ODBC接口将MySQL表添加为Access链接表时触发报错
- 环境信息:MySQL实例包含
dev、test两个schema,两个schema内的表结构完全一致 - 异常特征:连接字符串中配置
NO_I_S=1参数前一日可正常运行,当日执行失败;后续测试新建aldb库,连接aldb、dev库时链接功能正常,仅连接test库时抛出上述错误,已明确指定连接的目标schema,仍无法正常拉取表结构
复现代码
Public Sub start() Const dbAttachedODBC = 536870912 Const dbAttachSavePWD = 131072 Const AppEnum As String = "TEST" Dim tDefs As TableDefs Set tDefs = Application.CurrentDb.TableDefs Dim tDef As TableDef Dim stLocalTableName As String Dim stRemoteTableName As String Dim stConnect As String Dim stDatabase As String Dim AttributeLong As Long If AppEnum = "TEST" Then stDatabase = "test" Else stDatabase = "dev" End If stLocalTableName = "venditore" stRemoteTableName = "venditore" stConnect = "ODBC;DRIVER=MySQL ODBC 8.0 Unicode Driver;SERVER=localhost;PORT=3306;DATABASE=" & stDatabase & ";UID=root;PWD=root;NO_I_S=1;FULL_COLUMN_NAMES=1;NO_BIGINT=1;BIG_PACKETS=1;FOUND_ROWS=1;" AttributeLong = dbAttachSavePWD Set tDef = Application.CurrentDb.CreateTableDef(stLocalTableName) With tDef '.Name = stLocalTableName .Connect = stConnect .SourceTableName = stRemoteTableName .attributes = AttributeLong End With tDefs.Append tDef
故障根因
报错直接由NO_I_S=1参数的元数据读取逻辑触发:
- 开启
NO_I_S=1后,MySQL ODBC驱动不会从information_schema读取精确的表结构元数据,会改用SHOW COLUMNS语句拉取字段信息 - 当前使用root账号连接,拥有全库访问权限,连接
test库时,驱动拉取元数据过程中会匹配到跨schema的同名可见对象、或test库下venditore表关联的同名字段视图/异常索引,最终返回重复字段名 - Access在创建链接表时会校验字段唯一性,检测到重复字段名即抛出3191错误。
dev、aldb库连接正常,是因为这两个库的元数据返回结果不存在重复字段。
修复方案
按优先级依次操作:
- 移除连接字符串中的
NO_I_S=1参数。该参数仅用于兼容没有information_schema访问权限的数据库账号,root账号无需开启,开启后反而会出现元数据读取不准的问题,移除后驱动会读取准确的单表结构,直接解决重复字段问题 - 若必须保留
NO_I_S=1配置,给SourceTableName增加显式schema限定,将代码中.SourceTableName = stRemoteTableName修改为.SourceTableName = "& stDatabase & "." & stRemoteTableName & "`",强制驱动仅读取目标schema下的指定表,避免拉取到其他schema的同名对象字段 - 执行
SHOW COLUMNS FROM test.venditore语句检查返回结果,确认test库下的venditore表是否存在重复字段、关联视图字段冲突、表索引损坏问题,修复异常结构后再执行链接 - 删除Access本地已存在的同名旧链接表,清理本地ODBC表结构缓存后重启Access,再重新执行链接操作,避免旧缓存结构干扰校验。
内容的提问来源于stack exchange,提问作者AlFin
相关产品推荐
相关产品推荐

