what is the best way to delete a set of records during insert?

I have created a trigger that is supposed to avoid a (lead) record being inserted if it contains an email found in another (contact) record. I am able to get the trigger to update (lead) fields if a match is found, however I want it to delete the (lead) record/s instead of inserting them, i.e., I do not want the record/s to be inserted if a match is found. I get the following error:DML statement cannot operate on trigger.new or trigger.old:
below is my trigger code, what I must do to get the trigger to fire successfully on a match?

trigger triggerULDC on Lead(before insert){

map<string,list<Contact>> BObjMap = new map<string,list<Contact>>();
for(Contact contact : [Select Id, Name, email From Contact]){
    if(BObjMap.get(contact.email) == null){
        BObjMap.put(contact.email, new list<Contact>());
    }
    BObjMap.get(contact.email).add(contact);
}

List<Lead> listLeadsToDelete = new List<Lead>();
for(Lead lead : trigger.new){
    if(BObjMap.containskey(lead.email)){
    listLeadsToDelete.add(lead);
    continue;
    }
    }
    delete listLeadsToDelete;

}

Answer

What follows is a trivial trigger that will delete a lead that is considered “duplicate” based on email address. Ideally, you would want more criteria, such as choosing at minimum last name, email, phone, and company, but this is just to get the creative juices flowing.

Note that the magic happens by calling clone on the record; we can’t DML on Trigger.new records, but simply by cloning them, we skirt around that limitation. On completion of a duplicate record in the UI, users will see the following error:

Record deleted
The record you attempted to access has been deleted. The user who deleted this record may be able to recover it from the Recycle Bin. Deleted data is stored in the Recycle Bin for 15 days. 

Unfortunately, we can’t customize or intercept this message, so it’s probably better to limit this logic to automatic processes, such as web to lead, etc. Following is the code that I produced to demonstrate the logic.

trigger deleteDuplicateLead on Lead (after insert) {
    Lead[] dupes = new Lead[0];
    Set<String> email = new Set<String>(), dupEmail = new Set<String>();
    for(Lead record: Trigger.new)
        email.add(record.email);
    email.remove(null);
    for(Lead record: [SELECT Id, Email FROM Lead WHERE Email IN :email])
        if(!Trigger.newMap.containsKey(record.id))
            dupEmail.add(record.Email);
    for(Lead record: Trigger.new)
        if(dupEmail.contains(record.Email))
            dupes.add(record.clone(true));
        else
            dupEmail.add(record.Email);
    delete dupes;
}

Attribution
Source : Link , Question Author : Bartley , Answer Author : sfdcfox

Leave a Comment