You need to sign in to do that
Don't have an account?
Too Many DML Statements: 151 Error
Hello,
I'm trying to write a trigger that updates the Account when a Contact underneath it is updated. I only want to populate a given field if it is updated or populated so that it doesn't overwrite to a blank value if the Account field is populated but the Contact field is not.
From researching around, it seems like I have a loop. From the other codes I've looked at and the research I've done, I cannot figure out how to eliminate this loop or what my code should like in order to be "out of the loop" so if someone has direction on that, it would be very much appreciated because I have no idea how to get it out of the loop.
The Too Many DML Statements error that I'm getting is not being caused by the actual code that I put it, but rather the code below is causing another trigger I have to encounter the Too Many DML Statements error.
Here is the new code I put into Salesforce. After I had this trigger up and running in Salesforce, I started getting the error on other Triggers:
trigger updateAccount on Contact(after insert, after update){
List<ID>AccountIds = new list <Id>();
List<Account> accounts = new List<Account>();
List <Contact> Contacts = new List <Contact>();
for(Contact c: Trigger.new){
AccountIds.add(c.AccountId);
}
accounts = [Select Id from Account where ID IN :AccountIDs];
Contacts = [Select Id, AccountID from Contact where AccountID In:AccountIDs];
For(Contact c:Trigger.new){
If(c.TV_Alerts_Present__c !=null){
Account a = new account (id=c.accountid, TV_Alerts_Present__c = c.TV_Alerts_Present__c); update a;}
If(c.TV_Average_Trace_Size__c !=null){
Account a = new account (id=c.accountid, TV_Average_Trace_Size__c = c.TV_Average_Trace_Size__c); update a;}
If(c.TV_Broken_Traces__c !=null){
Account a = new account (id=c.accountid, TV_Broken_Traces__c = c.TV_Broken_Traces__c); Update a;}
If(c.TV_Instrumentation_Installed__c !=null){
Account a = new account (id=c.accountid, TV_Instrumentation_Installed__c = c.TV_Instrumentation_Installed__c); Update a;}
If(c.TV_Is_Dormant__c !=null){
Account a = new account (id=c.accountid, TV_Is_Dormant__c = c.TV_Is_Dormant__c ); Update a;}
If(c.TV_Is_Paying__c !=null){
Account a = new account (id=c.accountid, TV_Is_Paying__c = c.TV_Is_Paying__c ); Update a;}
If(c.TV_Language_Installed__c !=null){
Account a = new account (id=c.accountid, TV_Language_Installed__c = c.TV_Language_Installed__c); Update a;}
If(c.TV_Last_Login__c !=null){
Account a = new account (id=c.accountid, TV_Last_Login__c = c.TV_Last_Login__c); Update a;}
If(c.TV_Max_Hosts__c !=null){
Account a = new account (id=c.accountid, TV_Max_Hosts__c = c.TV_Max_Hosts__c ); Update a;}
If(c.TV_Max_Trace_Size__c !=null){
Account a = new account (id=c.accountid, TV_Max_Trace_Size__c = c.TV_Max_Trace_Size__c); Update a;}
If(c.TV_Min_Trace_Size__c !=null){
Account a = new account (id=c.accountid, TV_Min_Trace_Size__c = c.TV_Min_Trace_Size__c ); Update a;}
If(c.TV_Number_of_Apps__c !=null){
Account a = new account (id=c.accountid, TV_Number_of_Apps__c = c.TV_Number_of_Apps__c); Update a;}
If(c.TV_Number_of_Hosts__c !=null){
Account a = new account (id=c.accountid, TV_Number_of_Hosts__c = c.TV_Number_of_Hosts__c); Update a;}
If(c.TV_Number_of_Requests__c !=null){
Account a = new account (id=c.accountid, TV_Number_of_Requests__c = c.TV_Number_of_Requests__c); Update a;}
If(c.TV_Number_of_Traces__c !=null){
Account a = new account (id=c.accountid, TV_Number_of_Traces__c = c.TV_Number_of_Traces__c); Update a;}
If(c.TV_Number_of_Users__c !=null){
Account a = new account (id=c.accountid, TV_Number_of_Users__c = c.TV_Number_of_Users__c); Update a;}
If(c.TV_Recent_Annotations__c !=null){
Account a = new account (id=c.accountid, TV_Recent_Annotations__c = c.TV_Recent_Annotations__c); Update a;}
If(c.TV_Rum_Present__c !=null){
Account a = new account (id=c.accountid, TV_Rum_Present__c = c.TV_Rum_Present__c ); Update a;}
If(c.TV_Tracelyzer_Installed__c !=null){
Account a = new account (id=c.accountid, TV_Tracelyzer_Installed__c = c.TV_Tracelyzer_Installed__c ); Update a;}
If(c.TV_Traces_Present__c !=null){
Account a = new account (id=c.accountid, TV_Traces_Present__c = c.TV_Traces_Present__c); Update a;}
If(c.TV_Users_Invited__c !=null){
Account a = new account (id=c.accountid, TV_Users_Invited__c = c.TV_Users_Invited__c); Update a;}
}
}
After I added the above trigger, I started getting the Apex Trigger Error Message about Too Many DML statements due to the below trigger.
The error message I was getting was "There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex triger UpdateLeadContactOppDemoDeliveredTasks caused an unexpected exception, contact your adminitstrator. UpdateLeadContactOppDemoDeliveredTasks: System.LimitException: Too Many DML Statements: 151."
Here is the trigger the error said was causing the error:
trigger UpdateLeadContactOppDemoDeliveredTasks on Task (after delete, after insert, after undelete,
after update) {
// Updated on 2.28.13 to include only leads and contacts - opportunities were separated out
// Declare the variables
public set<Id> LeadIDs = new Set<Id>();
public list<Lead> LeadsToUpdate = new List<Lead>();
public set<Id> ContactIDs = new Set<Id>();
public list<Contact> ContactsToUpdate = new List<Contact>();
// Build the list of Leads and Contacts to update
if(Trigger.isInsert || Trigger.isUnDelete || Trigger.isUpdate){
for(Task t: Trigger.new){
if(t.whoid!=null && string.valueOf(t.WhoId).startsWith('00Q'))
LeadIDs.add(t.WhoId);
if(t.whoid!=null && string.valueOf(t.WhoId).startsWith('003'))
ContactIDs.add(t.WhoId);
}
}
if(Trigger.isDelete || Trigger.isUpdate){
for(Task t: Trigger.old){
if(t.whoid!=null && string.valueOf(t.WhoId).startsWith('00Q'))
LeadIDs.add(t.WhoId);
if(t.whoid!=null && string.valueOf(t.WhoId).startsWith('003'))
ContactIDs.add(t.WhoId);
}
}
// Update the Leads
if(LeadIDs.size()>0){
for(Lead l: [Select l.Id, l.Demos_Delivered_Count__c,
(Select Id From Tasks where Status = 'Demo Delivered' )
From Lead l where Id in :LeadIDs])
LeadsToUpdate.add(new Lead(Id=l.Id, Demos_Delivered_Count__c = l.Tasks.size()));
update LeadsToUpdate;
}
if(LeadstoUpdate != null && !LeadsToUpdate.isEmpty())
Database.update(LeadsToUpdate);
// Update the Contacts
if(ContactIDs.size()>0){
for(Contact c: [Select c.Id, c.Demo_Delivered_Count__c,
(Select Id From Tasks where Status = 'Demo Delivered')
From Contact c where Id in :ContactIDs])
ContactsToUpdate.add(new Contact(Id=c.Id, Demo_Delivered_Count__c = c.Tasks.size()));
update ContactsToUpdate;
}
if(ContactstoUpdate != null && !ContactsToUpdate.isEmpty())
Database.update(ContactsToUpdate);
}
Any help would be appreciated. I'm really struggling with this and all of the solutions that I have tried do not seem to be working.
Thank you in advance for your help!!
Hi ,
Your are using update (DML) in for loop. And we know salesforce has limit or 150 Dml in one context.
If your loop run 200 times than it user 200 Dml.
You can do this in one DML Just use a list of accout and add every account in this list and last after for loop update this list.
eg - List<account> alist = new List<account>();
For(Contact c:Trigger.new)
{
your if condation
alist.add(new Account (id=XXXXXXX ,......));
}
if(alist.size()>0)
update alist;
Thanks
Ashlekh
If you like this post than please mark it as solution.And dont forget to give me kudos.
D-Horse, the problem with using a list is you could have the same account in the list more than once causing a failure. For this reason I recommend using a Map or Set. Please see below for refactored code.
Hi
Use this code
If helps you then mark it as a solution and don't forget to give me kudo's
Thanks
Ashlekh
Very nice! Much cleaner than mine. I didn't have the time to do this yesterday ;-) Kudos for D-Horse.
HI ,
And Thanks for kudo's .
Please mark it as a solution as any one other will also get help.
Thanks
Ashlekh