You need to sign in to do that
Don't have an account?
Guru@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);
}
}
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);
}
}
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.
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
You will have to re-architect your solution to not need to create so many scheduled jobs.
Can You please send any sample code on behalf of this.....
that would be great helpful for us..
Thanks
Guru
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.