求助:解决Salesforce触发器Too many SOQL queries:101报错问题
解决Salesforce触发器"Too many SOQL queries: 101"报错
问题诊断
你提供的这段代码已经将SOQL移到循环外,所以报错根源不在这段代码本身,大概率是这段代码被嵌套在另一个循环(比如Trigger.new/Trigger.old的遍历循环)中执行,导致每次循环都触发一次SOQL查询,累计超过100次限制;或者触发器的其他逻辑存在循环内查询的情况。
解决步骤与优化代码
1. 确保SOQL仅执行一次
将SOQL查询放在所有循环的最外层,用Map存储查询结果,避免重复获取数据:
// 仅执行一次SOQL,将结果存入Map以快速查找 Map<Id, Pos_Item__c> posItemMap = new Map<Id, Pos_Item__c>([ SELECT Id, InProcess_Inventory_Stock__c FROM Pos_Item__c WHERE Id IN :posItemsWithInprocessInventory.keySet() ]); List<Pos_Item__c> posItemsToUpdate = new List<Pos_Item__c>(); // 遍历需要更新的ID集合,直接从Map取数据,无需再次查询 for(Id itemId : posItemsWithInprocessInventory.keySet()) { Pos_Item__c posItem = posItemMap.get(itemId); if(posItem != null) { // 简化空值判断 posItem.InProcess_Inventory_Stock__c = posItem.InProcess_Inventory_Stock__c == null ? 0 : posItem.InProcess_Inventory_Stock__c; posItem.InProcess_Inventory_Stock__c -= posItemsWithInprocessInventory.get(itemId); posItemsToUpdate.add(posItem); } } // 统一执行更新操作,减少DML次数 if(!posItemsToUpdate.isEmpty()) { update posItemsToUpdate; }
2. 排查外层循环与递归问题
- 检查这段代码是否被包裹在另一个循环中(比如遍历
Trigger.new的循环),如果是,将SOQL和数据处理移到外层循环之外。 - 检查触发器是否存在递归执行:更新
Pos_Item__c后可能再次触发同一个触发器,导致多次执行SOQL。可以通过静态变量控制递归:
public class TriggerHandler { private static Boolean isRecursive = false; public static void handlePosItemUpdate(List<Pos_Item__c> newItems) { if(isRecursive) return; isRecursive = true; // 你的业务逻辑代码 // ... isRecursive = false; } }
3. 定位SOQL消耗点
在触发器关键位置插入调试语句,查看SOQL查询次数的变化,定位消耗大量查询的逻辑:
System.debug('当前SOQL查询次数: ' + Limits.getQueries());
额外注意事项
- 确保同一事务内所有SOQL查询总数不超过100次(同步事务限制)。
- 避免在循环中执行任何SOQL或DML操作,所有查询和数据更新都要批量处理。
内容的提问来源于stack exchange,提问作者Kavya
相关产品推荐
相关产品推荐

