Apex触发器问题:修改非空邮寄街道仍触发错误
问题分析与解决思路
你的触发器逻辑出错的核心原因是没有对比字段修改前后的值,错误地用数据库旧值或单一新值做判断,导致正常修改操作也触发报错。你的需求是阻止用户“删除”Mailing Street字段值(即把原本有值的字段改为空),而非阻止所有修改操作。
具体问题点
原代码存在两个关键问题:
- 错误查询数据库中的Contact旧值,而非直接对比触发器提供的新旧记录值,导致判断逻辑偏离预期;
- 仅检查修改后的字段是否为空,没有结合修改前的状态——实际上只有“旧值有内容、新值为空”的场景才需要阻止。
修正方案
正确的逻辑是:先筛选出关联了“Pricing Letters”角色的Contact,再对比这类Contact的Mailing Street字段新旧值,仅当用户试图清空原本有值的字段时抛出错误。
修正后的代码
// 第一步:获取关联"Pricing Letters"角色的Contact ID集合 Set<Id> pricingLetterContactIds = new Set<Id>(); for(AccountContactRelation acr : [SELECT ContactId FROM AccountContactRelation WHERE Roles INCLUDES ('Pricing Letters') AND ContactId IN : Trigger.new]) { pricingLetterContactIds.add(acr.ContactId); } // 第二步:校验目标Contact的字段修改行为 for(Contact newCon : Trigger.new) { if(pricingLetterContactIds.contains(newCon.Id)) { Contact oldCon = Trigger.oldMap.get(newCon.Id); // 仅当旧地址有值、新地址为空时,阻止操作 if(oldCon.MailingStreet != null && newCon.MailingStreet == null) { newCon.addError('Mailing Street on Pricing Letter Contacts cannot be cleared'); } } }
关键改动说明
- 简化查询逻辑:直接从
AccountContactRelation提取目标Contact ID,避免额外查询Contact表,提升执行效率; - 精准对比新旧值:利用
Trigger.oldMap获取修改前的字段状态,Trigger.new获取修改后状态,精准定位“清空字段”的操作; - 缩小校验范围:仅对关联指定角色的Contact做校验,减少不必要的逻辑判断。
内容的提问来源于stack exchange,提问作者RobIsNotATechGuy
相关产品推荐
相关产品推荐

