我在尝试加载8,000条记录时遇到问题,这些记录触发了以下触发器,导致出现错误System.LimitException:SOQL查询太多:101因为这个问题..
trigger BeforeTaskTrigger on Task (after insert, after update) {
for(Task s : Trigger.new)
{
if ((s.Type == 'QRC')&&(s.Status=='Completed')) {
BusinessLogic.processUpdateInsertTask(s);
}
}
}
public static void processUpdateInsertTask (Task s){
List<Task> itemList = [select Id, Type, Status, ActivityDate, OwnerId from Task where accountId = :s.AccountId and status = 'Completed' and Type ='QRC' Order By ActivityDate Desc ];
List<Event> eventList = [select Id, Type, Status__c, ActivityDate, OwnerId, endDateTime from Event where accountId = :s.AccountId and Status__c = 'Completed' and Type ='QRC' Order By endDateTime Desc ];
List<Account> accountData = [Select Id, Last_QRC_Date__c, Last_QRC_FA__c from Account where Id = :s.AccountId];
if ((accountData!=null)&&(accountData.size()>0)){
Date eventDate;
if (eventList != null && eventList.size()>0){
eventDate = date.newinstance(eventList.get(0).endDateTime.year(), eventList.get(0).endDateTime.month(), eventList.get(0).endDateTime.day());
}
if ((itemList != null)&&(itemlist.size()>0)&&(eventList!=null)&&(eventList.size()>0)){
if (itemList.get(0).ActivityDate >= eventDate){
accountData.get(0).Last_QRC_Date__c = itemList.get(0).ActivityDate;
accountData.get(0).Last_QRC_FA__c = itemList.get(0).OwnerId;
update accountData;
}
else {
accountData.get(0).Last_QRC_Date__c = eventDate;
accountData.get(0).Last_QRC_FA__c = eventList.get(0).OwnerId;
update accountData;
}
}
else if ((itemList != null)&&(itemlist.size()>0)){
processTaskSpecialCases(accountData, itemList);
}
else if ((eventList!=null)&&(eventList.size()>0)){
processEventSpecialCases(accountData, eventDate, eventList);
}
else {
processDeletionCases (accountData);
}
}
}
如果你能帮我修改SOQL查询以提高效率,我将很高兴。
答案 0 :(得分:2)
您需要移动填充for循环的itemList和eventList 的查询。传统上,当您需要这样的信息时,您只需查询一次所需的所有内容,然后将其放入地图中以便以后查找。
例如:
// Get all the Account Ids
List<String> accountIds = new List<String>();
for (Task t : Trigger.new)
{
accountIds.add(t.AccountId);
}
Map<String, List<Task>> taskMap = new Map<String, List<Task>>(); // keyed by AccountId
for (Task t : [select Id, AccountId, Type, Status, ActivityDate, OwnerId from Task where accountId = :accountIds and status = 'Completed' and Type ='QRC' Order By ActivityDate Desc ])
{
List<Task> tasks = new List<Task>();
if (taskMap.containsKey(t.AccountId))
{
tasks = taskMap.get(t.AccountId);
}
tasks.add(t);
taskMap.put(t.AccountId, tasks);
}
此示例基于上面的itemList,为您提供了一个Map,该Map由属于该帐户的所有任务的帐户ID加密。当您需要引用该列表时,您只需键入地图并获取值(最重要的是,它只能作为您可以在整个触发器中使用的单个SOQL查询)。
看看APEX Best Practices,批量化代码是开发可扩展Salesforce应用程序的重要部分。