You need to sign in to do that
Don't have an account?
TracMikeL
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; } }
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
What limits are you hitting? You don't have any SOQL/DML inside loops or the like so its not the usual bulkify problems.
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;
}
}
I was able to take your idea of Keyset and it worked great. Coming from non Apex Language I always forget about that keyset!
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
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?
Yah I believe it should only ever have a max of 200 entries per trigger as well.
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
Probably he need to use future keyword so that can be on the safe side.
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.
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.
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.
Are u making use of future keyword?