1

I have created a batch apex and I get this error: Batch Apex: Too many SOQL queries: 201 while I don't have any SOQL query in a for loop. I suspect it is coming from the DatedConversionRate query but I don't see the issue.

Does anyone can help on this ?

global class UpdateFxRateForOpenOpps implements 
    Database.Batchable<sObject>, Database.Stateful {

    // instance member to retain state across transactions
    global Integer recordsProcessed = 0;
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(
            'SELECT ID, FX_EU__c, FX_Entity__c, CurrencyIsoCode, Entity__c FROM Opportunity ' + 
            'Where RecordType.Name IN (\'Renewals\', \'New Business\') AND isClosed=false'
        );
    }
    global void execute(Database.BatchableContext bc, List<Opportunity> scope){
        // process each batch of records
        List<DatedConversionRate> fxRates = [SELECT ConversionRate, 
                                                    IsoCode
                                             FROM DatedConversionRate
                                             WHERE StartDate=:System.today()];
        List<Opportunity> opps = new List<Opportunity>();
        for (Opportunity opp : scope) {
            if (opp.CurrencyIsoCode == 'EUR') {
                opp.FX_EU__c = 1;
            } else {
                opp.FX_EU__c = getRate(opp.CurrencyIsoCode, fxRates);
            }
            opps.add(opp);   
        }
        update opps;
    }    
    global void finish(Database.BatchableContext bc){
        System.debug(recordsProcessed + ' records processed. Shazam!');
        AsyncApexJob job = [SELECT Id, Status, NumberOfErrors, 
            JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob
            WHERE Id = :bc.getJobId()];
        // call some utility to send email
        //EmailUtils.sendMessage(job, recordsProcessed);
    }
    private Decimal getRate(String oppCurrency, List<DatedConversionRate> fxRates){
        Decimal rate;
        for (DatedConversionRate r: fxRates) {
            if (r.IsoCode == oppCurrency) {
                rate = r.ConversionRate;
            }
        }
        return rate;
    }

}
3
  • What is the batch size you are using? If it is greater than 200, then query on DatedConversionRate in the execute method is running that number of time. Each execution of the 'execute' method is a single transaction which means in a single transaction you are trying to execute more than 200 SOQL query , hence the above governor limit error. Try to reduce the batch size and check the result. You can try with the batch size of 1 Commented May 10, 2019 at 9:01
  • Do you have any triggers/PB/Flows on Opportunity ? Commented May 10, 2019 at 9:16
  • I didn't put anything for the batch size. Setting the batch size to 1 solved the issue thanks.
    – AB5
    Commented May 10, 2019 at 13:42

1 Answer 1

2

What is the batch size? Try reducing it. The problem can also be in Opportunity trigger if its not bulkified. Try to run this in execute anonymous and see the number of soql you reach:

List<Opportunity> opp = [SELECT id from Opportunity limit 200];
update opp;

You must log in to answer this question.

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