删除ODBC链接CACHE的Access表记录时报错3197如何解决
错误3197(假并发报错)根因
你的场景完全排除真实并发访问,报错本质是Access ACE引擎做删除前的行版本校验不匹配,和多用户争抢数据无关,触发原因基本是两类:一是近期Office 2201版本迭代更新了ACE引擎的ODBC解析逻辑,二是Cache数据库端、ODBC驱动配置的隐式变更导致本地缓存的记录值和数据源实时返回值存在精度/格式偏差。
两种操作的逻辑差异可以直接佐证这个判断:
- 直接执行DELETE查询可正常生效:因为该操作是直接将SQL语句下发给Cache数据库执行,不会走ACE引擎本地的行版本二次校验流程
- Recordset.Delete、手动选中记录删除失败:这两种操作会先把记录拉取到Access本地缓存,执行删除前ACE会重新拉取目标行做值比对,只要存在微小的格式/精度差,就会抛出多用户修改的假报错
可落地解决方案(按生效优先级排序)
- 优先调整代码逻辑,绕开ACE本地校验
不要再直接调用Recordset对象的Delete方法,改为用仅向前只读游标拉取待删除记录的主键,再通过执行DELETE查询的方式把删除逻辑下发给数据源执行,参考代码:
注意执行ODBC表的删除SQL时必须加Dim rs As DAO.Recordset Set rs = CurrentDb.OpenRecordset("SELECT 目标主键字段 FROM 链接Cache表 WHERE 你的筛选条件", dbOpenForwardOnly, dbReadOnly) If Not rs.EOF Then rs.MoveFirst Do While Not rs.EOF ' 单条执行,也可以把主键拼接为IN语句做批量删除提升效率 CurrentDb.Execute "DELETE FROM 链接Cache表 WHERE 目标主键字段 = " & rs!目标主键字段, dbSeeChanges + dbFailOnError rs.MoveNext Loop End If rs.Close Set rs = NothingdbSeeChanges参数,否则会触发权限类报错。 - 修复链接表的字段映射问题
这是ODBC链接表触发假3197错误的最常见配置问题:- 删除现有Cache表的Access链接,重新走链接表向导,选择ODBC数据源后,必须在向导步骤中明确指定Cache表的主键,不要让Access自动推断主键
- 如果Cache表存在RowVersion(行版本戳)类型字段,链接时必须选中该字段,ACE会自动用这个字段做行版本校验,不会逐字段比对值,从根源上避免精度/格式差导致的校验失败
- 链接完成后打开表设计视图,确认主键字段前有钥匙图标,没有的话重复上述步骤重新链接
- 回退存在已知bug的Office版本
你当前使用的64位 MSO 2201 Build 16.0.14827.20186版本,ACE引擎对ODBC数据源的浮点数、带时区日期字段的解析存在已知bug,会导致本地缓存值和数据源返回值存在精度差触发校验失败:- 打开任意Office组件,走「文件-账户-更新选项」路径先禁用自动更新
- 以管理员身份打开命令提示符,执行以下命令回退到无该bug的稳定版本:
cd "C:\Program Files\Common Files\microsoft shared\ClickToRun" officec2rclient.exe /update user updatetoversion=16.0.14729.20260 - 调整ODBC驱动配置
打开你配置的Cache数据库ODBC数据源,关闭以下三个会修改返回值的选项:浮点数精度自动适配、日期自动转换为本地时区、字符串字段自动去除尾部空格,这些选项会导致ODBC返回给Access的值和数据库实际存储值存在差异,触发校验失败。
内容的提问来源于stack exchange,提问作者Tralala
相关产品推荐
相关产品推荐

