Salesforce批量化代码 - 这尚未批量化吗?

时间:2014-07-18 18:45:48

标签: for-loop triggers salesforce apex bulk

我们在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
     }

为什么我在沙盒中运行代码时仍然遇到上述错误?我以为我照顾了这个问题,但显然这里还有别的东西?请帮助..我需要指向正确的方向。

提前感谢您的协助

1 个答案:

答案 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次更新记录,但那是另一天的战斗;)