如何从for循环中获取SOQL查询

时间:2018-11-18 16:43:57

标签: for-loop salesforce soql

已添加代码。

我在这里一直在寻找解决方案,但找不到解决方案,请帮忙!

我有三个对象(A,B和C)。 A查找B,而B是C的主节点(详细信息)。 A和C都有许多与每个B记录相关的记录。

我想运行一个作业,该作业从对象C获取记录的子集(通常大约为5,000条记录)。然后遍历每个对象,并在对象A上获得查找相同对象B记录的记录,汇总对象A的数字字段,然后将其放在C记录上。

我已经成功地将此代码用于小规模的<100个Object C记录。但是每个对象C记录都需要一个新的SOQL查询,因为在获得所有对象C记录之后,我会在for循环中对它们进行迭代。另外,我知道这不是循环执行查询的最佳实践。

我该如何使用它?由于记录与对象B共享关系,是否有另一种方法可以从匹配的对象A记录中获取数据?还是有某种方法可以拉出两个列表,一个是对象C,一个是对象A。然后汇总对象A的记录并将列表排列成一些方式?

谢谢!

代码:

public class nightlyJob {
    public static void updateNumbers(){
        integer I = 29; 
        List<ObjectC__c> CUpdateList = new List<ObjectC__c>();
        List<ObjectC__c> CpullList = 
                  [SELECT ID, Index__c, ObjectB__r.id
                  FROM ObjectC__c
                  WHERE Index__c = :I];
                for(ObjectC__c s : CpullList){
                        List<ObjectA__c> AList =
                            [SELECT ObjectB__c, Number__c
                            FROM ObjectA__c
                            WHERE ObjectB__c = :s.ObjectB__r.Id];
                    decimal NumSum = 0;
                    for(ObjectA__c a : AList){
                        NumSum = a.Number__c + NumSum;
                    }
                    s.Num__c = NumSum;
                    CUpdateList.add(s);
                }
        update CUpdateList;
    }            
}

1 个答案:

答案 0 :(得分:0)

您似乎目前确实缺少几个基本概念。

SFDC开发中面临的最大问题是“数据库”操作非常昂贵且受到严格限制。这不仅仅是“最佳实践”的问题:如果在单个事务中超过了这些限制-SOQL调用的数量,返回的记录数量,更新的记录数量,DML语句的数量等-您的事务将失败。有关详细信息,请在线搜索“ Salesforce执行主管和限制”。

您可以编写在这些限制范围内工作的代码,但是有一些学习困难。

首先,学习将集合与SOQL查询一起使用,以使SOQL查询脱离循环。这就是所谓的“批量化”,它是SFDC发展的基础:

String.contains(subString: String)

接下来,请尽可能使用“ SOQL聚合函数”。示例:在此处的代码中,您可以使用“ SUM()”和“分组依据”,而不是通过循环执行这些计算:

    List<ObjectC__c> CpullList = 
              [SELECT ID, Index__c, ObjectB__r.id
              FROM ObjectC__c
              WHERE Index__c = :I];
    // Create a map with the results of this query.  
    // key=ObjectC__c.Id, value = Object__c record
    Map<Id, ObjectC__c> objCmap = Map<Id, ObjectC__c>(CpullList);

    // Build a set of all the Object_B id's from this result set
    Set<Id> objBids = new Set<Id>();
    for (ObjectC__c record : CpullList) {
        objBids.add(record.ObjectB__r.id);
    }

    // Now you can use only one SOQL query instead of a loop
    List<ObjectA> AList = [SELECT ObjectB__c, Number__c
                        FROM ObjectA__c
                        WHERE ObjectB__c in:objBids];

您可以继续此过程并应用这些思想来使代码更高效。

但是,即使在使方法尽可能高效地工作之后,由于要处理的记录数仍然可能会遇到限制。到那时,您将需要了解Batchable接口,Queuable接口和@future调用(如何处理大量记录,在事务之间进行拆分),对于单个SO答案而言,信息实在太多了。 / p>