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
TracMikeLTracMikeL 

Bulkify Account To Contact Trigger

Hey Guys,

 

In the below trigger I am updating records on Contact Record from values on the Account. How can I bulkify this? It hits the Script limitations otherwise.

 

 

trigger trac_PrimaryContact on Account (after insert, after update) {
	
	List<String> updPContacts = new List<String>();
	
	for (Account a :Trigger.new) {	
		

		if(a.Contact__c != null) {
						
			updPContacts.Add(a.Affnet_Contact__c);
		}
	}
	
	
	//Update Contacts
	if(updPContacts.Size() > 0) {
				
		Contact[] myCons = [SELECT Id, FirstName, LastName, Email, Title FROM Contact WHERE ID IN :updPContacts];
										
		for(Contact myC :myCons) {
			
			for (Account a :Trigger.new) {	
								
				if(myC.Id == a.Contact__c) {
					
					myC.FirstName = a.First_Name__c;
					myC.LastName = a.Last_Name__c;
					myC.Email__c = a.Email__c;
					myC.Title = a.Title__c;
				}
			}
		}
		
		update myCons;			
	}	
}

 

 

Best Answer chosen by Admin (Salesforce Developers) 
kritinkritin

Hi Marmot74,

 

See the below logic and give your comment, And hope it will help you more.

 

trigger trac_PrimaryContact on Account (after insert, after update) {
 
 
 Map<String,Account> mapAccount=new Map<String,Account>();
 List<Contact> updatecontact=new List<Contact>();
 
 for (Account a :Trigger.new) { 
  

  if(a.Contact__c != null) {
      
   mapAccount.put(a.Affnet_Contact__c,a);
  }
 }
 
 
 //Update Contacts
 if(updPContacts.Size() > 0) {
  
  for(Contact myC :[SELECT Id, FirstName, LastName, Email, Title FROM Contact WHERE ID IN      :mapAccount.keySet()]){
  
   if(!mapAccount.isEmpty()){
    Account tempAccount=MapAccount.get(myC.Id);
    myC.FirstName = tempAccount.First_Name__c;
    myC.LastName = tempAccount.Last_Name__c;
    myC.Email__c = tempAccount.Email__c;
    myC.Title = tempAccount.Title__c;
      
   }
   updatecontact.Add(myC);

  }
  
  update updatecontact;
 }


 
}


 

All Answers

bob_buzzardbob_buzzard

What limits are you hitting?  You don't have any SOQL/DML inside loops or the like so its not the usual bulkify problems.  

kritinkritin

Hi Marmot74,

 

See the below logic and give your comment, And hope it will help you more.

 

trigger trac_PrimaryContact on Account (after insert, after update) {
 
 
 Map<String,Account> mapAccount=new Map<String,Account>();
 List<Contact> updatecontact=new List<Contact>();
 
 for (Account a :Trigger.new) { 
  

  if(a.Contact__c != null) {
      
   mapAccount.put(a.Affnet_Contact__c,a);
  }
 }
 
 
 //Update Contacts
 if(updPContacts.Size() > 0) {
  
  for(Contact myC :[SELECT Id, FirstName, LastName, Email, Title FROM Contact WHERE ID IN      :mapAccount.keySet()]){
  
   if(!mapAccount.isEmpty()){
    Account tempAccount=MapAccount.get(myC.Id);
    myC.FirstName = tempAccount.First_Name__c;
    myC.LastName = tempAccount.Last_Name__c;
    myC.Email__c = tempAccount.Email__c;
    myC.Title = tempAccount.Title__c;
      
   }
   updatecontact.Add(myC);

  }
  
  update updatecontact;
 }


 
}


 

This was selected as the best answer
TracMikeLTracMikeL

I was able to take your idea of Keyset and it worked great. Coming from non Apex Language I always forget about that keyset!

TrickTrick

Hi Kritin,

 

Wouldn't the line given below give u a soql limitation error.

 

for(Contact myC :[SELECT Id, FirstName, LastName, Email, Title FROM Contact WHERE ID IN      :mapAccount.keySet()])

 

Thanks,

 

Trick

bob_buzzardbob_buzzard

I don't see why that would happen.  The mapAccount has a maximum of one entry per account being processed by the trigger, so that would result in a maximum of 200 results wouldn't it?

TracMikeLTracMikeL

Yah I believe it should only ever have a max of 200 entries per trigger as well.

TrickTrick

I am new to salesforce ,therefore, my knowledge is not as good as yours.So I might e wrong, I am trying to learn from this forum.

 

Since he has used select statement in the for loop and if this loop runs for more than 20 times the code will give soql limitation error.Ok,that might not be the case because he has used IN operator which will fetch all the records in one go and pass on to the object.

 

If there are 500 records in the keyset and as far as my knowledge goes we won't be able to update 500 records and we will get error as we cannot update more than 200 records when we are updating across objects.

 

Please correct me if I am wrong

TrickTrick

Probably he need to use future keyword so that can be on the safe side.

TracMikeLTracMikeL

That query is not in the trigger loop. It will only run once.

 

Trust me :) I just used this code to load 500K+ records via the data loader with 200 records per call. No errors.

 

The for loop runs the query ONCE, then looks through each returned record. Does not query each record every time.

TrickTrick

 

Are u not trying to update contact records from the account object.?.I just wants to know that.Instead of updating 200, can u update more  than 200 records such as 201 in one call.

 

 

 

 

TracMikeLTracMikeL

Yes but the trigger handles 200 records at a time. So the 201st account record with be in the 2nd instance of the trigger execution.

TrickTrick

Are u making use of future keyword?