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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.