在UPDATE查询中使用Allen Browne的ConcatRelated(VBA)遇报错问题
解决Access UPDATE查询中调用自定义聚合函数的不可更新错误
问题原因
你的UPDATE查询直接关联了视图dbo_vw_EPIC_PRD_EMP_TEMPLATE,并且在SET子句中调用了自定义聚合函数GetList,这种组合会导致Access无法识别可更新的目标记录,触发“Operation must use an updateable query”错误。
解决方案
方法一:使用关联子查询更新
将聚合逻辑放到子查询中,直接关联DOETrainingList的字段获取结果,让Access明确更新目标:
UPDATE DOETrainingList SET EMP1110 = ( SELECT GetList( "LNK_TEMPLT_ID", "dbo_vw_EPIC_PRD_EMP_TEMPLATE", "USER_ID = """ & DOETrainingList.EMPDOT1 & """"", ", ", Chr(13) & Chr(10) ) FROM dbo_vw_EPIC_PRD_EMP_TEMPLATE WHERE USER_ID = DOETrainingList.EMPDOT1 GROUP BY USER_ID ) -- 仅更新存在对应记录的行,避免空值覆盖 WHERE EXISTS ( SELECT 1 FROM dbo_vw_EPIC_PRD_EMP_TEMPLATE WHERE USER_ID = DOETrainingList.EMPDOT1 );
方法二:通过临时表中转更新
先将聚合结果存入临时表,再用临时表关联原表更新,这种方式更直观且兼容性更好:
- 创建临时表存储聚合结果:
SELECT DOETrainingList.SUI, DOETrainingList.EMPDOT1, GetList( "LNK_TEMPLT_ID", "dbo_vw_EPIC_PRD_EMP_TEMPLATE", "USER_ID = """ & [dbo_vw_EPIC_PRD_EMP_TEMPLATE].[USER_ID] & """"", ", ", Chr(13) & Chr(10) ) AS TemplateIds INTO Temp_TemplateIds FROM DOETrainingList INNER JOIN dbo_vw_EPIC_PRD_EMP_TEMPLATE ON DOETrainingList.EMPDOT1 = dbo_vw_EPIC_PRD_EMP_TEMPLATE.USER_ID GROUP BY DOETrainingList.SUI, DOETrainingList.EMPDOT1;
- 关联临时表更新原表:
UPDATE DOETrainingList INNER JOIN Temp_TemplateIds ON DOETrainingList.SUI = Temp_TemplateIds.SUI SET DOETrainingList.EMP1110 = Temp_TemplateIds.TemplateIds;
- (可选)更新完成后删除临时表:
DROP TABLE Temp_TemplateIds;
注意事项
- 检查
GetList函数的参数格式,确保分隔符、条件字符串拼接无语法错误 - 如果
dbo_vw_EPIC_PRD_EMP_TEMPLATE是链接的SQL Server视图,建议在SQL Server端完成聚合(比如用STRING_AGG函数),再返回结果给Access,效率会更高 - 批量更新前建议先测试少量记录,避免数据错误
内容的提问来源于stack exchange,提问作者Headache
相关产品推荐
相关产品推荐

