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
NishanNishan 

Trigger to catch duplicate from multiple fields

Hi Everyone,

                              I am new to apex so this should be a simple question. I have a custom object with string fields. No duplicate should occur in any of these fields(before insert and before update).

                              I just want to add the duplictes to a list and in the end allow insert only if the list is NULL.

bob_buzzardbob_buzzard

An easier solution is to mark the fields as unique - that way the platform will enforce the uniqueness.  You can only do this on three fields however.

nitinkhunal.ax1786nitinkhunal.ax1786

Trigger CheckDuplicate on Object__c(before insert, before update){

List<Object__c> Obj=new List<Object__c>([Select id, CustomField1__c, CustomField2__c  from Object__c]);

 

For(Object__c obj1:tirgger.new)

{

    if(obj1.CustomField1__c==obj.CustomField1__c && obj1.CustomField2__c==obj.CustomField2__c)

    {

              obj1.addError('record already exist');

     }

}

}

 

You can check number of fields by this way just adding those in if statement. Try this one

bob_buzzardbob_buzzard

I don't think this would work very well with a large number of records in the system - the SOQL query wouldn't scale past 50,000 and you could well hit governor limits if you are processing several thousand records for each entry in the trigger.new list (which could contain 200 entries).

 

I'd be more inclined to build a list of the field values present in the trigger, then query for all records whose field value is present in the list, then process the results to match up the dupes.

 

As I say, you can do this through configuration which will be a lot more efficient as the database layer will take care of it.

NishanNishan

Hi Bob,

             The uniqueness that the platform offers is restricted to just one field, right? I want uniqueness between 3 different fields.

NishanNishan

Hi Nitin,

              I tried your code but the following error ocurs

 

 

Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Custom_obj__c> at line 11 column 19

 

 

 

hisalesforcehisalesforce
String field1=trigger.new[0].field1;
String field2=trigger.new[0].field2;
String field3=trigger.new[0].field3;
//Whichever field has to be unique...
List<Object> counting =[Select Id  from Object where field1=:field1 and field2=:field2 and field3=:field3];
if(allrecord.size()!=0)
          Trigger.new[0].adderror('Duplicate record');

 

 

Intead of trigger.new bulkify the trigger.

I think this will be helpful.

 

NishanNishan

Hisalesforce,

                         I used your code by replacing the 'and' in the query with 'or'. The edited code is given below

 

trigger test on Mason__c (before insert, before update)
{
  
String field1=trigger.new[0].Name;
String field2=trigger.new[0].Phone_No_2__c;
String field3=trigger.new[0].Phone_No_3__c;
//Whichever field has to be unique...
List<Mason__c> counting =[Select Id  from Mason__c where Name=:field1 or Name=:field2 or Name=:field3 
                                              or Phone_No_2__c=:field1 or Phone_No_2__c=:field2 or   Phone_No_2__c=:field3 
                                              or Phone_No_3__c=:field1 or Phone_No_3__c=:field2 or Phone_No_3__c=:field3];
if(counting.size()!=0)
          Trigger.new[0].adderror('Duplicate record');

 Mason__c is the object and name is used as phone_no_1.  

 

         But the trigger is always fired for non-duplicate entries too. Is there something I am missing ?

hisalesforcehisalesforce

 

 

Since you are using or condition just for test purpose.

 

use this approach

String field1=trigger.new[0].field1;

 

When you set all field1,field2  and field3..

if(field1==null || field1=='')

     field1='*****';

if(field2==null || field2=='')

     field1='*@@@';

 

Put this if condition before doing soql;

If this work ,let me know...

Also there need some improvement in the code.as of now there may arise null exception.

 

List<Mason__c> counting=new List<mason__c>(); 
try{
counting =[Select Id from Mason__c where Name=:field1 or Name=:field2 or Name=:field3 or Phone_No_2__c=:field1 or Phone_No_2__c=:field2 or Phone_No_2__c=:field3 or Phone_No_3__c=:field1 or Phone_No_3__c=:field2 or Phone_No_3__c=:field3];
}
catch(exception ex)
{
}

 

 

 

 

 

NishanNishan

It is still preventing non-duplicate entries too. The same problem happens with another trigger code I tried for this purpose. In that trigger it points the current record Id itself (the record in Trigger.new) as the record in which duplicate is found.

 

        Is it possible that any of my salesfoce configuration is getting in the way of the trigger ?

 

 

Sailappa VigneshSailappa Vignesh

Hi Nishan,

 

Here is the trigger to check duplicate based on three fields.

 

 

 

trigger leadDuplicatePreventer on Lead

    Map<String, Lead> leadMap = new Map<String, Lead>();

    Map<String, Lead> leadMap1 = new Map<String, Lead>();

    Map<String, Lead> leadMap2 = new Map<String, Lead>();

    for (Lead lead : System.Trigger.new) {

        // Make sure we don't treat an email address that  

        // isn't changing during an update as a duplicate.  

        if ((System.Trigger.isInsert || System.Trigger.isUpdate || (lead.Email != 

            (lead.FirstName != 

                               (before insert, before update) {

                    System.Trigger.oldMap.get(lead.Id).Email) &&

                    System.Trigger.oldMap.get(lead.Id).FirstName) && (lead.LastName != 

                    System.Trigger.oldMap.get(lead.Id).LastName) )) {

            // Make sure another new lead isn't also a duplicate  

            if (leadMap.containsKey(lead.Email) && (leadMap1.containsKey(lead.FirstName)

) &&(leadMap2.containsKey(lead.LastName)) ) {

                lead.addError('Invalid Data');

               }

            else {

                leadMap.put(lead.Email, lead);

                leadMap1.put(lead.FirstName,lead);

                leadMap2.put(lead.LastName,lead);

            }

       }

    }

    // Using a single database query, find all the leads in  

    // the database that have the same email address as any  

    // of the leads being inserted or updated.  

    for (Lead lead : [SELECT Email,FirstName,LastName FROM Lead

2.KeySet()]) {

        Lead newLead = leadMap.get(lead.Email);

        newLead.addError('Review All');

         /*                      

       Lead newLead1 = leadMap1.get(lead.Company);

        newLead1.Company.addError('A lead with this Company'

    }

}

                      WHERE Email IN :leadMap.KeySet() and FirstName IN:leadMap1.KeySet() and LastName IN:leadMap

                               + 'address already exists.');*/

NishanNishan
Hi Vignesh, Thanks for your code. But I need all three fields to be unique in and of itself. They are 3 phone number fields for one record and no record should have the same phone number in any order( phone 1 cannot be equal to phone 2).
mike_merinomike_merino
i "liked" Vignesh's code, but it seemed to be a puzzle (e.g.  line ten should be line two, etc) to be figured out, the pieces were there but in random order.  I needed to do a dup check on two lead fields: company and a custom field processing_origin__c and here's what worked for me;
===============
String errMsg ='A Lead with this Company & Processing Origin already exists';

    Map<String, Lead> leadMap1 = new Map<String, Lead>();
    Map<String, Lead> leadMap2 = new Map<String, Lead>();
    for (Lead lead : System.Trigger.new)
    {
        if (System.Trigger.isInsert || (System.Trigger.isUpdate &&
                    (lead.company != System.Trigger.oldMap.get(lead.Id).company || lead.processing_origin__c != System.Trigger.oldMap.get(lead.Id).processing_origin__c)))
            {
            // Make sure another new lead isn't also a duplicate 
            if (leadMap1.containsKey(lead.company) && leadMap2.containsKey(lead.processing_origin__c))
               {
                lead.addError(errMsg);
               }
            else
               {
                leadMap1.put(lead.company,lead);
                leadMap2.put(lead.processing_origin__c,lead);
               }
       }
    }
    // Using a single database query, find all the leads in 
    // the database that have the same email address as any 
    // of the leads being inserted or updated. 
    for (Lead lead : [SELECT company,processing_origin__c FROM Lead where company IN:leadMap1.KeySet() and processing_origin__c IN:leadMap2.keySet()])
    {
        Lead newLead = leadMap1.get(lead.company);
        newLead.company.addError(errMsg);
    }
Basil Dobek 6Basil Dobek 6
mike_merino's solution seems to have a flaw in that it could theoretically flag too many errors.  For example:

    Existing leads:
        Company  Origin
           C1      O1
           C2      O2
           
    New Leads:
        Company  Origin
           C1      O2     -  Will be erroneously flagged as a duplicate. 
           C2      O1     
AYUSH AGRAWAL 33AYUSH AGRAWAL 33
Here is the code that i used without Trigger.old:

trigger avoidDupInsert on Account(before insert)
{
   Map<String,Account> newAccountsMap = new Map<String,Account>();
   Map<String,Account> existingAccountsMap = new Map<String,Account>();
   for(Account acc: Trigger.new)
   {
      newAccountsMap.put(acc.Name,new Account(Name = acc.Name,Phone = acc.Phone));
   }
   for(Account acc : [Select name,phone from Account where name in: newAccountsMap.keySet()])
   {
      existingAccountsMap.put(acc.Name,new Account(Name = acc.Name,Phone = acc.Phone));
   }
   for(Account acc : Trigger.new)
   {
      if(existingAccountsMap.get(acc.Name) == newAccountsMap.get(acc.Name))
      {
        acc.addError('Duplicate Record -----');
      }
   }
}
AYUSH AGRAWAL 33AYUSH AGRAWAL 33
Without map with Set also possible. The below is to find duplicate based on two account field Name and Phone Number:

trigger avoidDupInsertOnAccount on Account(before insert,before update)
{
  Set<Account> existingSet = new Set<Account>();
  Set<String> accPhoneList = new Set<String>();
  
  for(Account acc: Trigger.new)
  {
    accPhoneList.add(acc.Phone);
  }
  for(Account acc : [Select name,phone from Account where Phone in: accPhoneList])
  {
     existingSet.add(getAccountWithDupKey(acc));
  }
  for(Account acc : Trigger.new)
  {
    if(existingSet.contains(getAccountWithDupKey(acc)))
    {
       acc.addError('----- Duplicate Record -----');
    }
  }
  
  public Account getAccountWithDupKey(Account acc)
  {
     return(new Account(Name = acc.Name,Phone = acc.Phone));
  }
}