[SalesForce] Batch Apex: Too many SOQL queries: 201

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;
    }

}

Best Answer

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;
Related Topic