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 10 years, 2 months ago by  Shubham.
    • This discussion was modified 9 years, 11 months ago by  Forcetalks.
    shariq replied 7 years, 8 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.

  • [adinserter block='9']
  • 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.