1

How can I get child records in the below code?

global class BatchToUpdateOppReps implements Database.Batchable<sObject>{ 


    global Database.QueryLocator start(Database.BatchableContext BC){

        return Database.getQueryLocator([select id,Territory_Rep__c,Specification_Rep__c,
                                         (select id,account__c,C_S_Opportunity__c,Account_Role__c 
                                           from CS_Opportunity_Related_Accounts__r  
                                           where Account_Role__c in ('Representative','Territory') 
                                           and Account__c!=null) 
                                           from C_S_Opportunity__C 
                                           where Specification_Rep__c=null 
                                           and Territory_Rep__c=null 

                                           ]);
    }
    global void execute(Database.BatchableContext BC,List<C_S_Opportunity__C>scope){

        List<C_S_Opportunity__c> oppUpdates=new List<C_S_Opportunity__c>();
        for(C_S_Opportunity__C Opp:(List<C_S_Opportunity__c>)scope){


            if(!Opp.CS_Opportunity_Related_Accounts__r.isEmpty()){
               C_S_Opportunity__c  csopp=new C_S_Opportunity__c(id=opp.Id);

                for(opp_related_accounts__c oppRelAcc:Opp.CS_Opportunity_Related_Accounts__r){

                    if(oppRelAcc.Account_Role__c=='Representative'){
                         csopp.Specification_Rep__c=oppRelAcc.Account__c;

                    }else if(oppRelAcc.Account_Role__c=='Territory'){
                        csopp.Territory_Rep__c=oppRelAcc.Account__c;

                        }
                }
                oppUpdates.add(csopp);
            }
        }

        if(!oppUpdates.isEmpty() && oppUpdates.size()>0){
            update oppUpdates;
        }
    }
    global void finish(Database.BatchableContext BC){

    }
} //End

1 Answer 1

2

It is generally best to structure the batchable so that the query in the start method does not include a sub-select as that sub-select can exceed limits.

In your case that would mean changing to this query:

select id, account__c, C_S_Opportunity__c, Account_Role__c,
        C_S_Opportunity__r.Id,
        C_S_Opportunity__r.Territory_Rep__c,
        C_S_Opportunity__r.Specification_Rep__c
from CS_Opportunity_Related_Account__c  
where Account_Role__c in ('Representative','Territory') 
and Account__c != null
and C_S_Opportunity__r.Specification_Rep__c = null
and C_S_Opportunity__r.Territory_Rep__c = null

(Not sure why you are returning Specification_Rep__c and Territory_Rep__c when they are always null.)

Then the execute method could look something like this:

global void execute(Database.BatchableContext bc, List<CS_Opportunity_Related_Account__c> scope) {

    Map<Id, C_S_Opportunity__c> m = new Map<Id, C_S_Opportunity__c>();
    for(CS_Opportunity_Related_Account__c ora : scope) {
        Id oppId = ora.C_S_Opportunity__c;
        Id accId = ora.Account__c;
        if (ora.Account_Role__c == 'Representative') {
            m.put(oppId, new C_S_Opportunity__c(Id = oppId, Specification_Rep__c = accId));
        } else if(ora.Account_Role__c=='Territory') {
            m.put(oppId, new C_S_Opportunity__c(Id = oppId, Territory_Rep__c = accId));
        }
    }
    update m.values();
}
1
  • Also the data can be stale. Think I just saw Andy Fawcett post recently that for large batches you should even re-query the scope itself for that reason.
    – Adrian Larson
    Dec 18, 2017 at 13:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .