You need to sign in to do that
Don't have an account?
Kaja
I've looked in the apex documentation for bulk triggers. It's bad to put soql statements in a for loop. the batch size for each trigger can be from 1 to 200. if the batch size is high, having a soql statement in the for loop will give you the soql error.
System.Exception: Too many SOQL queries: 21
Hi,
I am new to Apex trigger and need to get rid of the following error while doing bulk updates on Opportunity.
Update Row Failed:
tocOpportunityAfterUpdate: execution of AfterUpdate
caused by: System.Exception: Too many SOQL queries: 21
Trigger.tocOpportunityAfterUpdate: line 8, column 42
tocOpportunityAfterUpdate: execution of AfterUpdate
caused by: System.Exception: Too many SOQL queries: 21
Trigger.tocOpportunityAfterUpdate: line 8, column 42
The following is the trigger which needs modification to avoid the above bulk update error.
Code:
trigger tocOportunityAfterUpdate on Opportunity (after update) { integer i=0; try { for (Opportunity o : Trigger.new) { String id = Trigger.new[i].Id; if (Trigger.new[i].Billing_Report_Date__c != null && (Trigger.old[i].Billing_Report_Date__c == null || Trigger.old[i].Billing_Report_Date__c != Trigger.new[i].Billing_Report_Date__c)) { Opportunity[] oppList = [Select o.tocClonedFrom__c, o.RecordType.Name, o.Id, o.Billing_Report_Date__c, (Select Id, Billing_Report_Date__c From Opportunities__r) From Opportunity o where (o.tocClonedFrom__c=:id) or o.Id = :id]; for (Opportunity op : oppList) { if(op.RecordType.Name == 'Payment' && op.Id != id ) { Opportunity updOpp = new Opportunity(Id=op.Id); updOpp.Billing_Report_Date__c = Trigger.new[i].Billing_Report_Date__c; update updOpp; } if((op.tocClonedFrom__c == id && op.RecordType.Name == 'Payment') || op.Id == id ) { tfCommissionOpportunity__c[] commOppsList = op.Opportunities__r; for(tfCommissionOpportunity__c commOpp : commOppsList){ tfCommissionOpportunity__c updCommOpp = new tfCommissionOpportunity__c(Id=commOpp.Id); updCommOpp.Billing_Report_Date__c = Trigger.new[i].Billing_Report_Date__c; update updCommOpp; } } } } i += 1; } } catch (Exception e){ } }
I've looked in the apex documentation for bulk triggers. It's bad to put soql statements in a for loop. the batch size for each trigger can be from 1 to 200. if the batch size is high, having a soql statement in the for loop will give you the soql error.
It would be very useful for me, if you people modified the above code to get rid of that error.
thanks
venkat
Also, you could consider using oldMap and newMap to retrieve Opportunities passed into the Trigger, rather than having to iterate through them (eg use Trigger.oldMap.get(id) instead of i += 1 stuff).
Have a look through samples of Triggers on these forums for ideas.
I could update upto 1700 Opportunities with the date values, but after that its showing the same SOQL error! :-(
Why are you involving 20,000 records? Are you trying to load them via the Data Loader? If so, you can reduce the batch size.
If your query really does need 20,000 records, then I think you're out of luck.
What are your actual business requirements? How often should this be called -- just once or on every update? What are you trying to accomplish?
Hi TLF,
I was going thru the link which you sent and got something about sforce execution Governor limits!
I had put the select query outside the for loop and done one time update after the for loop only. So there is no problem in doing bulk update. As i mentioned before, I could update 95% records successfully,only 5% records are failed. Does my code causing this problem of updating this 5% failed records? When i try running the failed records,then 2% records updating rest 3% failed. Then again running 3% failed records, 2% passed and 1% failed.
Is there any other approach to process 100% records successfully at a single shot.
Here is my updated code. Request you to have a look at this and correct me, if i did something wrong with this code.
This is not created for the bulk update but for other purpose. This trigger caused the problem while doing bulk load thru Apex Data loader. Hope you people understand my problem.
Awaiting for your valuable feedback! :-)
It looks to me like you could be getting stuck in an infinite recursion situation, because you are trying to update Opportunities within a trigger that fires after update of Opportunity objects. This is from the Apex documentation:
Triggers can also modify other records of the same type as the records that initially fired the trigger. For example, if a trigger fires after an update of contact A, the trigger can also modify contacts B, C, and D. Because triggers can cause other records to change, and because these changes can, in turn, fire more triggers, the Apex runtime engine considers all such operations a single unit of work and sets limits on the number of operations that can be performed to prevent infinite recursion. See Understanding Execution Governors and Limits.
Boss,
Could you please help me on this how to update the Opportunities in bulk of 20000Records without having any SOQL Queries error. I am getting the error after updating 1700Records.
Though number of failed records only 400 ot of 21000, it is not correct. I have to update the trigger in such a way that it should not throw any too many SOQL queries error or script elements error.
As per the apex documentation http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm , i should be able to retrieve as many as 20000 records, but failed even after 1700records.
Whats the resolution for this problem? Any change still i can do with my updated code?
As i am new to Apex class, i couldn't replace with apex class. Please guide me
regards
venkat
You must be right Sir! :-)
Could you provide me the sample apex class with respect to the replacement of this trigger?
I am new to apex as i mentioned before. :-
Apex class should be added where and how it should be invoked by opportunity after update?
plz guide me sir
It is BOTH one time update and will update the opportunities frequently. :-(
Once they would get the billing report dates, they would do the bulk update once in a month. Sometimes,update happen one by one. So i need to handle both. My concern is that it is start throwing 100 error records(caused by: System.Exception: Too many script statements: 30001) even after 1700 successful records update and it goes upto 400errors out of 21000 records.
We have come to some conclusion like you said.
During Bulk load, We can inactivate the trigger. Then do bulk load and then Activate the Trigger. This is straight forward job.
This is the standard way of doing in many companies.
Meanwhile, we are also finding if any alternatives are there.