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
Guru@SfCloudGuru@SfCloud 

Facing the Issue like OpportunityTrigger : System.LimitException: Too many SOQL queries: 101

Hi,

I am firing the trigger on Opportunity and calling the schedule class when I Upload the data like 200 records it is showing the error like too many soql queries and can any one help me to resolve this issue........

Trigger is:
trigger OpportunityTrigger on Opportunity (before update, before insert) {   
    //if(!SalesStageOrderIterable.doneit) {
        SalesStageOrderIterable.doneit = true;
        Map<String, Opportunity> opportunityMap = new Map<String, Opportunity>();
        Map<String, List<String>> oppToStagesMap = new Map<String, List<String>>();
        for(integer i=0; i<Trigger.size; i++) {
           
            Opportunity newOpportunity = Trigger.new[i];
            newOpportunity.SkipStages__c = true;
            opportunityMap.put(newOpportunity.Name+newOpportunity.CloseDate+newOpportunity.AccountId,newOpportunity);
            System.debug('DPK: newOpportunity: '+newOpportunity);
            //if(!newOpportunity.Override_Missing_Fields__c) {
                //SalesStageFieldChecker.checkFields(newOpportunity);           
            //}
           
            //Opportunity oldOpportunity = Trigger.old[i];
            if((Trigger.isInsert && newOpportunity.LeadSource != 'Sales Generated')
               || (!newOpportunity.Trigger_Ignore_Stage_Update__c &&
               (Trigger.isUpdate && newOpportunity.StageName != Trigger.old[i].StageName)
              )) {
                  System.debug('DPK:0.1');
                  //check change is 1 step, otherwise add to stagetracking Map<Id,List<String>>
                  String oldStageName;
                  if(Trigger.isUpdate) {
                      oldStageName = Trigger.old[i].StageName;
                      System.debug('DPK:0.2:'+oldStageName);
                  } else if(Trigger.isInsert) {
                      oldStageName = 'Start';
                      System.debug('DPK:0.3:'+oldStageName);
                  }
                  String newStageName = newOpportunity.StageName;
                 
                  System.debug('DPK - old:new: '+oldStageName+':'+newStageName);
                  Iterator<Sales_Opportunity_Stage_Order__c> iter = new foo().Iterator();
                  System.debug('DPK:iter: '+iter);
                  List<String> stagesToPass = oppToStagesMap.get(newOpportunity.Name+newOpportunity.CloseDate+newOpportunity.AccountId);
                  if(stagesToPass == null) {
                      stagesToPass = new List<String>();
                      oppToStagesMap.put(newOpportunity.Name+newOpportunity.CloseDate+newOpportunity.AccountId,stagesToPass);
                  }
                  System.debug('DPK:iter: '+iter);
                  boolean breakout = false;
                  boolean newStageSeen = false;
                  while(iter.hasNext() && !breakout) {
                      Sales_Opportunity_Stage_Order__c stage = iter.next();
                      if(stage.StageName__c == oldStageName) {
                          System.debug('DPK:1:'+oldStageName);
                         
                          while(iter.hasNext() && !breakout) {
                              System.debug('DPK:2');
                              Sales_Opportunity_Stage_Order__c nextStage = iter.next();
                              if(nextStage.StageName__c == newStageName) {
                                  System.debug('DPK:3:'+newStageName);
                                  breakout = true;
                                  newStageSeen = true;
                              } else {    
                                  newOpportunity.ShowMessage__c = true;
                                  newOpportunity.MessageShown__c = false;
                                  stagesToPass.add(nextStage.StageName__c);
                              }
                          }
                      }
                     
                  }
                  if(!newStageSeen) {
                      stagesToPass.clear();
                      newOpportunity.ShowMessage__c = false;
                  }
                  stagesToPass.add(newOpportunity.StageName);
                 
              }
            newOpportunity.Trigger_Ignore_Stage_Update__c = false;
        }
   
    List<Task> tasksToInsert = new List<Task>();

   
   
    for(String oppId : oppToStagesMap.keySet()) {
        System.debug('DPK:oppId'+oppId);
        Opportunity thisOpp = opportunityMap.get(oppId);
        String requestedStage = thisOpp.StageName;
        List<String> stagesToPass = oppToStagesMap.get(oppId);
        System.debug('DPK:stagesToPass:'+stagesToPass);           
        if(stagesToPass != null && !stagesToPass.isEmpty()) {
            if(thisOpp.SkipStages__c == true || stagesToPass.size()==1 || (stagesToPass.size() == 2 && stagesToPass[0] == 'Marketing Qualified')) {           
                for(integer i=0; i<stagesToPass.size(); i++) {
                   
                    if(i==0) {
                        thisOpp.StageName = stagesToPass[i];   
                    } else {
                        DateTime inXMinutes = DateTime.now().addMinutes(i);
                        String hour = String.valueOf(inXMinutes.hour());
                        String min = String.valueOf(inXMinutes.minute());
                        String ss = String.valueOf(inXMinutes.second());
                       
                        String triggerId = EncodingUtil.convertToHex(crypto.generateAesKey(128)).substring(1,20).toUpperCase();
                        String cronJobName = 'OpportunityStageUpdate@'+inXMinutes+':'+triggerId;
                        String nextFireTimeCron = ss + ' ' + min + ' ' + hour + ' * * ?';
                        String jobName = thisOpp.Name+':'+stagesToPass[i]+':'+inXMinutes;

//it is showing error from below line where calling the schedulable method and error is too many soql Queries                        
OpportunitySchedulable schedulable = new OpportunityStageUpdateSchedulable(jobName,thisOpp.id,stagesToPass[i],thisOpp.Name,thisOpp.CloseDate,thisOpp.AccountId);
                       
                        System.schedule(jobName, nextFireTimeCron, schedulable);
                        System.debug('DPK:stagesToPass[i]'+stagesToPass[i]);           
                       
                       
                       
                    }
                }
            }
            //else {
            //    thisOpp.addError('You have skipped some Stages. Please check "Skip Stages" if you want to continue.');
            //}
        }
       
        }
    //}
   
}

Schedule class is:
==============

global class OpportunitySchedulable implements Schedulable {

    private String cronJobName;
    private String stageName;
    private Id opportunityId;
    private String opportunityName;
    private Date closeDate;
    private Id accountId;
   
    global OpportunityStageUpdateSchedulable(String cronJobName, Id opportunityId, String stageName, String opportunityName, Date closeDate, Id accountId) {
        this.cronJobName = cronJobName;
        this.stageName = stageName;
        this.opportunityId = opportunityId;
        this.opportunityName = opportunityName;
        this.closeDate = closeDate;
        this.accountId = accountId;
       
    }
   
    global void execute(SchedulableContext ctx) {
       
        //newOpportunity.Name+newOpportunity.CloseDate+newOpportunity.AccountId
        List<Opportunity> opps;
       
        if(!String.isBlank(opportunityId)) {
            opps = [SELECT id FROM Opportunity WHERE id = :opportunityId];   
        }
        if(opps == null || opps.isEmpty()) {
            opps = [SELECT id FROM Opportunity WHERE Name = :opportunityName AND CloseDate = :closeDate AND AccountID = :accountId];
        }
        Opportunity theOpp;
        if(!opps.isEmpty()) {
            theOpp = opps[0];
        }
        if(theOpp != null) {
            theOpp.StageName = stageName;
            theOpp.Trigger_Ignore_Stage_Update__c = true;
            update theOpp;
        }
       
        CronTrigger cr =[SELECT id FROM CronTrigger WHERE CronJobDetail.Name = :cronJobName];

        System.abortJob(cr.id);   
    }
}


pbattissonpbattisson
If you look at the documentation here (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_scheduler.htm) you will see the following:

Use extreme care if you’re planning to schedule a class from a trigger. You must be able to guarantee that the trigger won’t add more scheduled classes than the 100 that are allowed. In particular, consider API bulk updates, import wizards, mass record changes through the user interface, and all cases where more than one record can be updated at a time.

You are getting the error because you are creating too many schedule classes.
Guru@SfCloudGuru@SfCloud
Thanks Pbattisson,

But I am not able to find the solution by seeing the document and can you please review my  code and help me to sort out the mistake ..it's an urgent.

Thanks in advance
Guru
pbattissonpbattisson
There is no way to fix it with your existing code setup - you are trying to create too many scheduled jobs because you are doing one for each record and there is a maximum limit of 100 scheduled jobs.

You will have to re-architect your solution to not need to create so many scheduled jobs.
Guru@SfCloudGuru@SfCloud
Thanks Pbattisson,

Can You please send any sample code on behalf of this.....
that would be great helpful for us..

Thanks
Guru
pbattissonpbattisson
I cannot send any sample code for this - you need to update your system to not use this scheduled system in the way you are.

You would be best to go and try to see if your business requirement can be changed or clarified to remove th need to have more than 100 scheduled jobs created or ensure that only 100 or less opportunities are submitted at once.