Activity Forums Salesforce® Discussions Why is Trigger Not Working For Bulk Insert?

  • Why is Trigger Not Working For Bulk Insert?

    Posted by Shubham on March 22, 2016 at 1:45 pm

    I have created a trigger On Contact.

    My requirement is to check the given conditions before insert / before update and throw error when the conditions are true.
    - Duplicate Email is not allowed.
    - Contact cannot be Type 4.

    The Trigger is Working fine when I am inserting contact manually but it is not Working for Bulk insert. It is accepting Duplicate Email values for Bulk insert. Can anybody suggest me how to achieve that?

    Trigger Code---

    trigger checkEmail on Contact (before insert,after insert,before update) {
    	
        List conList = [select Email,Type__c from contact];
        
        for(Contact conToInsert : Trigger.New){
            
            for(Contact conToCompare : conList){
                if(conToInsert.Type__c == 'Type 4' ){
                    conToInsert.addError('Contact Cannot be Type 4');
                }
                else{
                    if(conToInsert.Email != null){
                        if(conToInsert.Email == conToCompare.Email){
                         conToInsert.addError('Same Email Found Cannot Insert');
                    }
                    } 
                }
                    
            }
        }
        
    }
    
    • This discussion was modified 8 years, 8 months ago by  Shubham.
    • This discussion was modified 8 years, 4 months ago by  Forcetalks.
    shariq replied 6 years, 2 months ago 5 Members · 5 Replies
  • 5 Replies
  • Gaurav

    Member
    March 22, 2016 at 3:08 pm

    Hello Shubham,

    You can Try adding this code to your trigger.

    trigger checkEmail on Contact (before insert,after insert,before update) {

    List<Contact> conList = [select Email,Type__c from contact];

    Integer counter = 0;
    for(Contact conToInsert : Trigger.New)
    for(Contact conToInsert1 : Trigger.New){
    if(conToInsert.Email == conToInsert1.Email)
    conToDelete.add(conToInsert);
    counter++;
    if(counter>1)
    conToInsert.addError('Same Email Found Cannot Insert');
    }

    for(Contact conToInsert : Trigger.New){

    for(Contact conToCompare : conList){
    if(conToInsert.Type__c == 'Type 4' ){
    conToInsert.addError('Contact Cannot be Type 4');
    }
    else{
    if(conToInsert.Email != null){
    if(conToInsert.Email == conToCompare.Email){
    conToInsert.addError('Same Email Found Cannot Insert');
    }
    }

    }

    }
    }

    }

    I hope this will help you.

  • Shubham

    Member
    March 23, 2016 at 7:50 am

    @gaurav Thanks, it worked.

  • Jayant

    Member
    March 23, 2016 at 12:41 pm

    The first for loop can cause performance issue: Suppose Trigger.New has 1000 or 2000 records then it will run for 1000*1000 = 1,000,000 or 2000*2000 = 2,000,000.

    You can use Set here for improving performance:

    Integer counter = 0;
    Set<String> uniqueEmails = new Set<String>();
    List<Contact> validContacts = new List<Contact>();
    Map<String, Contact> validContacts = new Map<String,Contact>();
    for(Contact conToInsert : Trigger.New) {
    if(conToInsert.Email != null) {
    Contact result = validContacts.get(conToInsert.Email)
    //If result is FALSE, then add Error to record.
    if(result != null) {
    conToInsert.addError("Duplicate Email Address.");
    }
    else if(result != null && conToInsert.Type__c == ‘Type 4’){
    conToInsert.addError("Contact Cannot be Type 4.");
    } else {
    //Everything okay

    validContacts.put(conToInsert.Email, result );
    }
    }
    }

    //Now check Contact with unique email against existing Contacts.
    //If there are more than 50000 Record, then this needs to be rewritten
    List<Contact> existingContacts = [select Email,Type__c from Contact Email in :validContacts.keySet()];

    for(Contact existingContact : existingContacts){
    Contact temp = validContacts.get(existingContact.Email);
    if(temp.id == null || temp.Type__c == ‘Type 4’) {
    //This is bad record, remove
    temp.addError("Duplicate Email or Type 4");
    validContacts.remove(temp);
    }
    }

    //These are valid record. Do whatever you want to do with them.
    List<Contact> updateOrInsertContact = validContacts.values();

    I hope this helps.

  • Parul

    Member
    September 19, 2018 at 9:16 pm

    Hello Shubham,

    You can Try adding this code to your trigger.

    trigger checkEmail on Contact (before insert,after insert,before update) {

    List<Contact> conList = [select Email,Type__c from contact];

    Integer counter = 0;
    for(Contact conToInsert : Trigger.New)
    for(Contact conToInsert1 : Trigger.New){
    if(conToInsert.Email == conToInsert1.Email)
    conToDelete.add(conToInsert);
    counter++;
    if(counter>1)
    conToInsert.addError(‘Same Email Found Cannot Insert’);
    }

    for(Contact conToInsert : Trigger.New){

    for(Contact conToCompare : conList){
    if(conToInsert.Type__c == ‘Type 4’ ){
    conToInsert.addError(‘Contact Cannot be Type 4’);
    }
    else{
    if(conToInsert.Email != null){
    if(conToInsert.Email == conToCompare.Email){
    conToInsert.addError(‘Same Email Found Cannot Insert’);
    }
    }

    }

    }
    }

    }

    I hope this will help you.

  • shariq

    Member
    September 19, 2018 at 10:26 pm

    Hi,

    Adding points to your code -

    • You need to put LIMIT 50000 in your query otherwise when more than 50000 records exist in database will give query exception.
    • Try to use one loop instead of two.
    • Most Important - Try to use context variables for the triggers.

    Hope this helps.

Log In to reply.

Popular Salesforce Blogs