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
Patrick G. BrownPatrick G. Brown 

Too Many DML Statements 151 Campaign Member Import

I have a trigger that works fine up to about 100 Campaign Members on import, but once I hit around 100 I receive the Too Many DML Statements 151 Error.  Anyone have an idea how to fix?
 
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

    Set<Id> leadIds = new Set<Id>();
    for (CampaignMember cml: Trigger.new){
        leadIds.add(cml.LeadId);
    }
    
    Map<Id, Lead> LeadMap2 = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
        
        //Loop through Campaign Member Leads and look for Current Campaign values
    for (CampaignMember cml: Trigger.new){
        List<Lead> leadToUpdate2=new List<Lead>();
        Lead associatedLead2 = LeadMap2.get(cml.LeadId);
        if(associatedLead2.Current_Campaign__c==NULL)
                {
                    associatedLead2.Status = 'In Campaign';
                    associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
                    leadToUpdate2.add(associatedLead2);
                }
        
        update leadToUpdate2;
    }

}

 
Best Answer chosen by Patrick G. Brown
jigarshahjigarshah
Patrick,

It seems that the statement below is not returning a Lead record instance for the specified Lead Record Id. This which causes the Current_Campaign__c check at line # 19 to fail since associatedLead2 is null.
Lead associatedLead2 = LeadMap2.get(cml.LeadId);

I would recommend updating the code as follows which checks first, if the associated Lead record Id exists in LeadMap2 and then assigns it for further usage.
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

	if(Trigger.isAfter){
	
		if(Trigger.isInsert){
		
			/*Set<Id> leadIds = new Set<Id>();
			for (CampaignMember cml: Trigger.new){
				leadIds.add(cml.LeadId);
			}*/
			
			Map<Id, Lead> LeadMap2 = 
				new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
								   FROM Lead 
								   WHERE Id IN :Trigger.newMap.keyset()]);
			
			List<Lead> leadToUpdate2 = new List<Lead>();
			Lead associatedLead2;
			
			//Loop through Campaign Member Leads and look for Current Campaign values
			for (CampaignMember cml: Trigger.new){
				
				if(LeadMap2.keySet().containsKey(cml.LeadId)){
				
					associatedLead2 = LeadMap2.get(cml.LeadId);
				
					if(associatedLead2.Current_Campaign__c == NULL)
					{
						associatedLead2.Status = 'In Campaign';
						associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
						leadToUpdate2.add(associatedLead2);
					}
				}//if
			}//for
			
			update leadToUpdate2;
		}
	}
}
Please mark this thread as SOLVED and answer as the BEST ANSWER if it helps address your issue.

All Answers

Prady01Prady01
Hi there, Small mistake. Try the below
 
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

    Set<Id> leadIds = new Set<Id>();
    for (CampaignMember cml: Trigger.new){
        leadIds.add(cml.LeadId);
    }
    
    Map<Id, Lead> LeadMap2 = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
        
        //Loop through Campaign Member Leads and look for Current Campaign values
    for (CampaignMember cml: Trigger.new){
        List<Lead> leadToUpdate2=new List<Lead>();
        Lead associatedLead2 = LeadMap2.get(cml.LeadId);
        if(associatedLead2.Current_Campaign__c==NULL)
                {
                    associatedLead2.Status = 'In Campaign';
                    associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
                    leadToUpdate2.add(associatedLead2);
                }
        

    }
    
        update leadToUpdate2;

}

Thanks 
PSM
jigarshahjigarshah
Patrick,

The issue with your existing code is that you are performing an update which is a DML operation within a for loop. This code performs a DML for every iteration of the for loop. Salesforce imposes a governor limit of being able to perform only 100 DML operations within a single execution context. Hence, when you try loading more than 100 Campaign Member records the code fails, since it hits the governor limits of 100 DML operations within a single execution context.

Hence, it is recommended that you Bulkify your code which means instead of performing a DML operation on a single record, perform it on a collection of records using a List. The below code performs the update on multiple Campaign Members and executes a single update for every 200 record batch of records prcoessed by the trigger and will help you address the issue.

Moreover, I noticed that you are iterating over Trigger.new to get the Lead Record Ids which is not requried and you can instead use Trigger.newMap.keyset() to accomplish the same with less code.
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

	if(Trigger.isAfter){
	
		if(Trigger.isInsert){
				
			Map<Id, Lead> LeadMap2 = 
				new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
								   FROM Lead 
								   WHERE Id IN :Trigger.newMap.keyset()]);
			
			List<Lead> leadToUpdate2 = new List<Lead>();
			
			//Loop through Campaign Member Leads and look for Current Campaign values
			for (CampaignMember cml: Trigger.new){
					
				Lead associatedLead2 = LeadMap2.get(cml.LeadId);
				
				if(associatedLead2.Current_Campaign__c == NULL)
				{
					associatedLead2.Status = 'In Campaign';
					associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
					leadToUpdate2.add(associatedLead2);
				}
			}//for
			
			update leadToUpdate2;
		}
	}
}
Please mark this thread as SOLVED and answer as the BEST ANSWER if it helps address your issue.
Patrick G. BrownPatrick G. Brown
Jigarshah, I reran the import and am now receiving a CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY:setLeadStatusandCurrentCampaign: execution of AfterInsert\ncaused by: System.NullPointerException: Attempt to de-reference a null object\nTrigger.setLeadStatusandCurrentCampaign: line 19, column 1:--.

Would you recommend taking the if statement out of the for loop as well?  Not sure how I could check the Current_Campaign__c for Null if I did that.

Your post back to me was perfect regarding the DML insert error.  After removing the update from within the for loop, it's much more efficient.  Thank you kindly.
jigarshahjigarshah
Patrick,

It seems that the statement below is not returning a Lead record instance for the specified Lead Record Id. This which causes the Current_Campaign__c check at line # 19 to fail since associatedLead2 is null.
Lead associatedLead2 = LeadMap2.get(cml.LeadId);

I would recommend updating the code as follows which checks first, if the associated Lead record Id exists in LeadMap2 and then assigns it for further usage.
trigger setLeadStatusandCurrentCampaign on CampaignMember (after insert) {

	if(Trigger.isAfter){
	
		if(Trigger.isInsert){
		
			/*Set<Id> leadIds = new Set<Id>();
			for (CampaignMember cml: Trigger.new){
				leadIds.add(cml.LeadId);
			}*/
			
			Map<Id, Lead> LeadMap2 = 
				new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status 
								   FROM Lead 
								   WHERE Id IN :Trigger.newMap.keyset()]);
			
			List<Lead> leadToUpdate2 = new List<Lead>();
			Lead associatedLead2;
			
			//Loop through Campaign Member Leads and look for Current Campaign values
			for (CampaignMember cml: Trigger.new){
				
				if(LeadMap2.keySet().containsKey(cml.LeadId)){
				
					associatedLead2 = LeadMap2.get(cml.LeadId);
				
					if(associatedLead2.Current_Campaign__c == NULL)
					{
						associatedLead2.Status = 'In Campaign';
						associatedLead2.Current_Campaign__c = cml.Campaign_Name__c;
						leadToUpdate2.add(associatedLead2);
					}
				}//if
			}//for
			
			update leadToUpdate2;
		}
	}
}
Please mark this thread as SOLVED and answer as the BEST ANSWER if it helps address your issue.
This was selected as the best answer
Patrick G. BrownPatrick G. Brown
Thanks again, Jigarshah.  There seems to be an error in line 23 of your code above.  I'm getting an error stating: Method does not exist or incorrect signature: void containsKey(Id) from the type Set<Id>.

I'll continue to work on it.  I really appreciate your excellent support.
jigarshahjigarshah
My bad syntax error. Update the if condition as follows at line # 23.
if(LeadMap2.containsKey(cml.LeadId))
Patrick G. BrownPatrick G. Brown
Jigarshah, I can't thank you enough.  It's error free now.  Thanks so much!
jigarshahjigarshah
Patrick, you are welcome. Glad I could help.