function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Anthony MealandAnthony Mealand 

How to pass a list into a batch process

Hello,

I have the below class that is called by a trigger. The Class runs through 2 lists of objects comparing them. One list is created by the trigger and the other is queried. The issue I am facing is that if I put my SOQL query inside of a loop, I will hit 'too many SOQL queries' limit if the trigger has > 100 records, however, if I query outside of the loop, I get the 'too many query rows' error.

To solve this, I'd like to run a batch which I haven't done before. I think I've worked out how to call the batch (commented in original code), but for this to work, I think need to either:

A) Pass the trigger list into the batch 
B) Return the queried list back into this class
C) Run another query in the batch to evaluate which records are being triggered 

I can't really work out how to do A or B, but I think it might have to do with a constructor maybe? (apologies - Im new to this and this is my frist trigger). If it's simple, I'd rather do this than go to option C (but I will if necessary).

I have posted below the class and the batch class. Any direction for this would be very appreciated.

Thanks!


public class SalesTrackingHandler {
    public void GetSalesData(List<School_Activities__c> SAS, List<School_Activities__c> OldSAS){
        List<Sales_Tracker__c> STS = New List<Sales_Tracker__c>(); // create a list of trackers that will be eventually entered to the system      
        
        Integer EOI = 0; // initiate the counting metrics
        Integer Paid = 0;
        Integer SU = 0;
        integer Count = -1;
        for(School_Activities__c SA : SAS){                        // Runs through all activities triggered
            Count = Count + 1;
            School_Activities__c OldSA = OldSAS.get(Count);        // finds the corresponding record details from before the record was saved
            if(SA.Sales_Tracker_Pendulum__c <> OldSA.Sales_Tracker_Pendulum__c){    // compares the old and new values of the 
                //BatchInclusionDetails Batch = New BatchInclusionDetails(SA);
                //Database.executeBatch(Batch);
                
                
                
                List<Inclusion_Details__c> INCS = [SELECT Id, School_ID__c, Lead_Source__c, Date_payment_received_WF__c,Sign_up_date__c,CreatedDate,Contact__r.NCS_Application_Primary_Season__c
                                                   from Inclusion_Details__c where Contact_Record_Type__c ='Young Person' AND Sales_Tracker_criteria__c = 'TRUE' AND
                                                      Sales_Tracker_Identifier__c like : '%' + SA.School__c + '%'];   // queries the contacts attached to this school for this season. Performed in loop to narrow search results below 50,000 limit
                Date Commence = date.newinstance(SA.Date_Sales_Tracking_commences__c.year(), 
                                         SA.Date_Sales_Tracking_commences__c.month(), SA.Date_Sales_Tracking_commences__c.day()); // sets datetime valid to compare created date against
                EOI = 0; // resets counting metrics
                Paid = 0;
                SU = 0;
                for(Inclusion_Details__c INC : INCS){            // loops through Inclusion detail records to assess against sales tracking metrics
                    if(SA.School__c == INC.School_ID__c && INC.Contact__r.NCS_Application_Primary_Season__c == SA.Season_Name__c){
                        IF(INC.Lead_Source__c == 'TRUE' && INC.CreatedDate >= Commence){      // checking criteria of EOI
                            EOI = EOI + 1;
                        }
                        if(INC.Date_payment_received_WF__c <> NULL){           // checking criteria of Paid
                            Paid = Paid +1;
                            if(INC.Sign_up_date__c <> NULL){                   // checking criteria of SU
                                SU = SU +1;
                            }                  
                        }                  
                    }
                }
                Sales_Tracker__c ST = new Sales_Tracker__c();        // create relevant Sales tracker record 
                    Date Yesterday = System.today() -1;
                ST.Name = SA.School__c + Yesterday.format();
                ST.School_Activity__c = SA.Id;
                ST.EOIs__c = EOI;
                ST.Paid__c = Paid;
                ST.SU__c = SU;
                   ST.Date__c = Yesterday;
                STS.add(ST);
                system.debug(ST);
            }
        }
        Database.insert(STS);         // insert all Sales tracker records to the system
    }
}



public class SalesTrackingHandler {
    public void GetSalesData(List<School_Activities__c> SAS, List<School_Activities__c> OldSAS){
        List<Sales_Tracker__c> STS = New List<Sales_Tracker__c>(); // create a list of trackers that will be eventually entered to the system      
        
        Integer EOI = 0; // initiate the counting metrics
        Integer Paid = 0;
        Integer SU = 0;
        integer Count = -1;
        for(School_Activities__c SA : SAS){                        // Runs through all activities triggered
            Count = Count + 1;
            School_Activities__c OldSA = OldSAS.get(Count);        // finds the corresponding record details from before the record was saved
            if(SA.Sales_Tracker_Pendulum__c <> OldSA.Sales_Tracker_Pendulum__c){    // compares the old and new values of the 
                //BatchInclusionDetails Batch = New BatchInclusionDetails(SA);
                //Database.executeBatch(Batch);
                
                
                
                List<Inclusion_Details__c> INCS = [SELECT Id, School_ID__c, Lead_Source__c, Date_payment_received_WF__c,Sign_up_date__c,CreatedDate,Contact__r.NCS_Application_Primary_Season__c
                                                   from Inclusion_Details__c where Contact_Record_Type__c ='Young Person' AND Sales_Tracker_criteria__c = 'TRUE' AND
                                                      Sales_Tracker_Identifier__c like : '%' + SA.School__c + '%'];   // queries the contacts attached to this school for this season. Performed in loop to narrow search results below 50,000 limit
                Date Commence = date.newinstance(SA.Date_Sales_Tracking_commences__c.year(), 
                                         SA.Date_Sales_Tracking_commences__c.month(), SA.Date_Sales_Tracking_commences__c.day()); // sets datetime valid to compare created date against
                EOI = 0; // resets counting metrics
                Paid = 0;
                SU = 0;
                for(Inclusion_Details__c INC : INCS){            // loops through Inclusion detail records to assess against sales tracking metrics
                    if(SA.School__c == INC.School_ID__c && INC.Contact__r.NCS_Application_Primary_Season__c == SA.Season_Name__c){
                        IF(INC.Lead_Source__c == 'TRUE' && INC.CreatedDate >= Commence){      // checking criteria of EOI
                            EOI = EOI + 1;
                        }
                        if(INC.Date_payment_received_WF__c <> NULL){           // checking criteria of Paid
                            Paid = Paid +1;
                            if(INC.Sign_up_date__c <> NULL){                   // checking criteria of SU
                                SU = SU +1;
                            }                  
                        }                  
                    }
                }
                Sales_Tracker__c ST = new Sales_Tracker__c();        // create relevant Sales tracker record 
                    Date Yesterday = System.today() -1;
                ST.Name = SA.School__c + Yesterday.format();
                ST.School_Activity__c = SA.Id;
                ST.EOIs__c = EOI;
                ST.Paid__c = Paid;
                ST.SU__c = SU;
                   ST.Date__c = Yesterday;
                STS.add(ST);
                system.debug(ST);
            }
        }
        Database.insert(STS);         // insert all Sales tracker records to the system
    }
}
James LoghryJames Loghry
Take a look at the following article, which explains it in a lot more detail than I ever could: http://andyinthecloud.com/2013/08/11/batch-worker-getting-more-done-with-less-work/

The gist is:  
  • Create a constructor in your batch class that takes the list as an argument.
  • Update the batch class to implement Database.Batchable<SomeType> where SomeType is String if you have a List<String>, or Account if you have a list of Accounts, etc.
  • Update the start method to return an Iterable<SomeType> instead of Database.getQueryLocator
  • Update the execute method to take the correct List argument.
Also, when you post code on these forums, please do so using the code format (< >) button.  It makes the code more readable and allows for easily copying / pasting if necessary.  Thanks!
Anthony MealandAnthony Mealand
Hi James,

Thanks for this - it's really, really useful (including the forum ettiquette). I think I've not managed to get my list into the start method which is great, but can I extend the execute method to take not only the returned query, but also the original list?