+ Start a Discussion
Todd B.Todd B. 

System.LimitException: Too many DML statements:

I created a Custom Object called SD_Member__c and on that object is a field Enrollment_Progress_Status__c which gets updated based on the result of a corresponding  Task.  I thought I did everything right, but periodically, I am getting a System.LimitException: Too many DML statements error.  Any ideas where my code may be causing this issue?
trigger Update_SD_Member_Enrollment_Progress_Status on Task (after update) {
/*
Automatically update the "Enrollment Progress Status" field, based upon the "Status" field 
of the last Member Task
*/

// Tasks that meet criteria, and new tasks to create
Task[] qualifiedTasks = new Task[0], newTasks = new Task[0];

Date dt=DateTime.now().addDays(1).date();
Date rt=DateTime.now().addDays(1).date();
    
// Map of SD Members
   Map<Id,SD_Member__c> members = new Map<Id,SD_Member__c>();

Map<id,Task> TaskMap = new Map<id,Task>([select id,RecordType.Name from Task 
                                         where id in : Trigger.newmap.keyset()]);
// Find qualifying tasks
for(Task record:Trigger.new)
        if(TaskMap.get(Record.id).RecordType.Name =='Member Outreach' &&
           record.isclosed == True)
           qualifiedtasks.add(record);
    
    // Obtain member ID values
    for(Task record:qualifiedtasks)
        members.put(record.whatid,null);
   
    // If there are any members to query, do so.
    if(!members.isempty())
        members.putall([select id, Enrollment_Progress_Status__c from SD_Member__c where id in :members.keyset()]);


 // For each qualifying task, check the current Enrollment_Progress_Status__c from SD_Member__c and assign
 // to the strStatus variable.  That way if the Task Status does not meet the critera below, the status 
 // will reamin it's current value 
for(Task record:qualifiedtasks) {
    String strStatus = members.get(record.whatid).Enrollment_Progress_Status__c;    

    // Set the strStatus based on the current Task Status value
      If (record.Status == 'Not Started' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Left Message w/ Person' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Member Hung Up' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Phone # Invalid' ){
          StrStatus = 'Phone # Invalid';}
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';} 
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}              
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Reached Target - Declined - Copay' ){
          StrStatus = 'Declined - Copay';}
      If (record.Status == 'Reached Target - Declined - Other' ){
          StrStatus = 'Declined - Other';}
      If (record.Status == 'Reached Target - Declined - Transport' ){
          StrStatus = 'Declined - Transportation';}
      If (record.Status == 'Reached Target - Requested Info' ){
          StrStatus = 'Decision Pending';}
      If (record.Status == 'Reached Target - Sent to Care Coach' ){
          StrStatus = 'Referred to Care Coach';}
      If (record.Status == 'Reached Target - Thinking About It' ){
          StrStatus = 'Decision Pending';}
          
    SD_Member__C SD1 = new SD_Member__C(ID=record.WhatId,Enrollment_Progress_Status__c=strStatus);
    update SD1; 
    
    }  }
Thanks, 

Todd B.
Best Answer chosen by Todd B.
Tugce SirinTugce Sirin
You are updating SD1 inside for loop. You should bulkify your code. Instead updating right away you can put your object inside a list and then update it outside of the for loop.

For example;
 
trigger Update_SD_Member_Enrollment_Progress_Status on Task (after update) {
/*
Automatically update the "Enrollment Progress Status" field, based upon the "Status" field 
of the last Member Task
*/

// Tasks that meet criteria, and new tasks to create
Task[] qualifiedTasks = new Task[0], newTasks = new Task[0];

Date dt=DateTime.now().addDays(1).date();
Date rt=DateTime.now().addDays(1).date();
    
// Map of SD Members
   Map<Id,SD_Member__c> members = new Map<Id,SD_Member__c>();

Map<id,Task> TaskMap = new Map<id,Task>([select id,RecordType.Name from Task 
                                         where id in : Trigger.newmap.keyset()]);
// Find qualifying tasks
for(Task record:Trigger.new)
        if(TaskMap.get(Record.id).RecordType.Name =='Member Outreach' &&
           record.isclosed == True)
           qualifiedtasks.add(record);
    
    // Obtain member ID values
    for(Task record:qualifiedtasks)
        members.put(record.whatid,null);
   
    // If there are any members to query, do so.
    if(!members.isempty())
        members.putall([select id, Enrollment_Progress_Status__c from SD_Member__c where id in :members.keyset()]);


 // For each qualifying task, check the current Enrollment_Progress_Status__c from SD_Member__c and assign
 // to the strStatus variable.  That way if the Task Status does not meet the critera below, the status 
 // will reamin it's current value 

//***********new list*****
List<SD_Member__C> sdMembers = new List<SD_Member__C>();
for(Task record:qualifiedtasks) {
    String strStatus = members.get(record.whatid).Enrollment_Progress_Status__c;    

    // Set the strStatus based on the current Task Status value
      If (record.Status == 'Not Started' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Left Message w/ Person' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Member Hung Up' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Phone # Invalid' ){
          StrStatus = 'Phone # Invalid';}
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';} 
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}              
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Reached Target - Declined - Copay' ){
          StrStatus = 'Declined - Copay';}
      If (record.Status == 'Reached Target - Declined - Other' ){
          StrStatus = 'Declined - Other';}
      If (record.Status == 'Reached Target - Declined - Transport' ){
          StrStatus = 'Declined - Transportation';}
      If (record.Status == 'Reached Target - Requested Info' ){
          StrStatus = 'Decision Pending';}
      If (record.Status == 'Reached Target - Sent to Care Coach' ){
          StrStatus = 'Referred to Care Coach';}
      If (record.Status == 'Reached Target - Thinking About It' ){
          StrStatus = 'Decision Pending';}
          
    SD_Member__C SD1 = new SD_Member__C(ID=record.WhatId,Enrollment_Progress_Status__c=strStatus);

//*******************adding object into list
    sdMembers.add(SD1);
    
    
    } 
  update sdMembers; 
 }

Let me know if this helps.

All Answers

Tugce SirinTugce Sirin
You are updating SD1 inside for loop. You should bulkify your code. Instead updating right away you can put your object inside a list and then update it outside of the for loop.

For example;
 
trigger Update_SD_Member_Enrollment_Progress_Status on Task (after update) {
/*
Automatically update the "Enrollment Progress Status" field, based upon the "Status" field 
of the last Member Task
*/

// Tasks that meet criteria, and new tasks to create
Task[] qualifiedTasks = new Task[0], newTasks = new Task[0];

Date dt=DateTime.now().addDays(1).date();
Date rt=DateTime.now().addDays(1).date();
    
// Map of SD Members
   Map<Id,SD_Member__c> members = new Map<Id,SD_Member__c>();

Map<id,Task> TaskMap = new Map<id,Task>([select id,RecordType.Name from Task 
                                         where id in : Trigger.newmap.keyset()]);
// Find qualifying tasks
for(Task record:Trigger.new)
        if(TaskMap.get(Record.id).RecordType.Name =='Member Outreach' &&
           record.isclosed == True)
           qualifiedtasks.add(record);
    
    // Obtain member ID values
    for(Task record:qualifiedtasks)
        members.put(record.whatid,null);
   
    // If there are any members to query, do so.
    if(!members.isempty())
        members.putall([select id, Enrollment_Progress_Status__c from SD_Member__c where id in :members.keyset()]);


 // For each qualifying task, check the current Enrollment_Progress_Status__c from SD_Member__c and assign
 // to the strStatus variable.  That way if the Task Status does not meet the critera below, the status 
 // will reamin it's current value 

//***********new list*****
List<SD_Member__C> sdMembers = new List<SD_Member__C>();
for(Task record:qualifiedtasks) {
    String strStatus = members.get(record.whatid).Enrollment_Progress_Status__c;    

    // Set the strStatus based on the current Task Status value
      If (record.Status == 'Not Started' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Left Message w/ Person' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Member Hung Up' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Phone # Invalid' ){
          StrStatus = 'Phone # Invalid';}
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';} 
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}              
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Reached Target - Declined - Copay' ){
          StrStatus = 'Declined - Copay';}
      If (record.Status == 'Reached Target - Declined - Other' ){
          StrStatus = 'Declined - Other';}
      If (record.Status == 'Reached Target - Declined - Transport' ){
          StrStatus = 'Declined - Transportation';}
      If (record.Status == 'Reached Target - Requested Info' ){
          StrStatus = 'Decision Pending';}
      If (record.Status == 'Reached Target - Sent to Care Coach' ){
          StrStatus = 'Referred to Care Coach';}
      If (record.Status == 'Reached Target - Thinking About It' ){
          StrStatus = 'Decision Pending';}
          
    SD_Member__C SD1 = new SD_Member__C(ID=record.WhatId,Enrollment_Progress_Status__c=strStatus);

//*******************adding object into list
    sdMembers.add(SD1);
    
    
    } 
  update sdMembers; 
 }

Let me know if this helps.
This was selected as the best answer
Tugce SirinTugce Sirin
I recevied and error message:  Error: Compile Error: Variable does not exist: sdMembers at line 72 column 5
If you received this error then you've missed a line that I've wrote. It's line 38 just above the for loop. I've declared a new list named sdMembers.
 
List<SD_Member__C> sdMembers = new List<SD_Member__C>();