我们在salesforce中有一个被称为触发器的类。使用Apex Data Loader时,此触发器会抛出错误oppafterupdate: System.LimitException: Too many SOQL queries: 101
我注释掉了一行代码,这些代码在我们编写的类中调用了以下静态方法,并且没有更多关于管理限制的错误。所以我可以验证下面的方法是罪魁祸首。
我是新手,但我知道应该批量化Apex代码,并且不应在循环内部使用DML(和SOQL)语句。您要做的是将对象放入集合中,并对集合使用DML语句。
所以我修改了下面的方法;我声明了一个列表,我在列表中添加了Task对象,并在列表中运行了DML语句。我在循环中注释掉了更新语句。
//close all tasks linked to an opty or lead
public static void closeTasks(string sId) {
List<Task> TasksToUpdate = new List<Task>{}; //added this
List<Task> t = [SELECT Id, Status, WhatId from Task WHERE WhatId =: sId]; //opty
if (t.isEmpty()==false) {
for (Task c: t) {
c.Status = 'Completed';
TasksToUpdate.add(c); //added this
//update c;
}
}
update TasksToUpdate; //Added this
}
为什么我在沙盒中运行代码时仍然遇到上述错误?我以为我照顾了这个问题,但显然这里还有别的东西?请帮助..我需要指向正确的方向。
提前感谢您的协助
答案 0 :(得分:3)
您已经“修复”了更新部分,但代码仍然在太多SELECT上失败。
我们需要查看你的触发器代码,但在我看来你在该触发器的循环中调用你的函数。因此,如果说200个机会被更新,你的函数被调用200次,在函数体中你有1个SOQL ...调用它超过100次并且繁荣,爆头。
尝试修改函数以传递ID集合:
Set<Id> ids = trigger.newMap().keyset();
betterCloseTasks(ids);
改进的功能可能如下所示:
public static void betterCloseTasks(Set<Id> ids){
List<Task> tasksToClose = [SELECT Id
FROM Task
WHERE WhatId IN :ids AND Status != 'Completed'];
if(!tasksToClose.isEmpty()){
for(Task t : tasksToClose){
t.Status = 'Completed';
}
update tasksToClose;
}
}
现在无论是更新1个还是数百个机会,您都有1个SOQL和1个更新操作。它仍然可以在一些其他限制上失败,例如在一次交易中最大10000次更新记录,但那是另一天的战斗;)