Apex Triggers - 6 (Prevent Duplication of Records)

แชร์
ฝัง
  • เผยแพร่เมื่อ 8 ต.ค. 2024
  • Revolutionize your Salesforce experience with Titan's powerful products
    Create and automate custom document templates directly from Salesforce - titandxp.com/p...
    Share, manage, and track the progress of e-signatures directly from Salesforce - titandxp.com/p...
    Create, automate, and track custom web forms directly from Salesforce - titandxp.com/p...
    Design and deploy dynamic no-code web portals and applications from Salesforce - titandxp.com/p...
    Automate your entire organization’s processes with digital workflow - titandxp.com/p...
    Create, automate, and track custom web surveys directly from Salesforce - titandxp.com/p...

ความคิดเห็น • 42

  • @stutinayak-ti5xp
    @stutinayak-ti5xp ปีที่แล้ว +3

    There is a loop hole here . This trigger is also firing whenever we are updating the other fields in the same trigger. I guess there has to be a oldmap check for the name here in order to avoid such scenario as during the course there are multiple triggers build on same object.

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว

      Hi Stuti , we cannot say that it is loophole actually this trigger is checking duplicates whenever any fields updates but the thing is it is only checking for names.

    • @mayanksharma139
      @mayanksharma139 ปีที่แล้ว

      @@sfdcninjas As Stuti said, We have to compare the old n value in order to prevent duplication otherwise it throw an error even if user update the record without chaning it's name as the record having the same name present in database

    • @krishnaCasukhela
      @krishnaCasukhela 11 หลายเดือนก่อน

      @@sfdcninjas, normally account names are not updated from the front end. so I don't understand why you are using trigger.isUdpate, it should be only trigger.isInsert..

    • @footballtalkswithsoham4430
      @footballtalkswithsoham4430 9 หลายเดือนก่อน

      Thanks for the help

  • @DS12399
    @DS12399 4 หลายเดือนก่อน

    instead of creating a loop for list to map we can use Map existingAccMap = new Map(accList);

    • @sfdcninjas
      @sfdcninjas  4 หลายเดือนก่อน

      nice suggestion Divya thanks

  • @agamyashvant5545
    @agamyashvant5545 7 วันที่ผ่านมา

    at line 17, we need to add null check isn't?

  • @ambritkumarsahu5179
    @ambritkumarsahu5179 ปีที่แล้ว +1

    Bro.. instead of using a map , can't we use a List there to store the Names.. Because we are not using the Values of the Map, only using the Keys.. Isn't it? Or am I missing something?

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว +1

      Hi Buddy , sorry for late reply , List can have duplicate values that's why we are using map here.

    • @sagarbora7768
      @sagarbora7768 7 หลายเดือนก่อน

      @@sfdcninjas But we could use set it's gonna have distinct values, Correct me if I'm wrong.

  • @dharmeshgupta3957
    @dharmeshgupta3957 ปีที่แล้ว +1

    very informative and helpful!!

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว

      Thank you Dharmesh

  • @soumya1713
    @soumya1713 20 วันที่ผ่านมา

    if you have more than 50k records then how can you handle it

    • @opeyemi_salesforce_journey
      @opeyemi_salesforce_journey 5 วันที่ผ่านมา

      you might need to go for more async solution like queueable or batch apex

  • @naveenyalamala
    @naveenyalamala 2 หลายเดือนก่อน

    You are trying to insert 4 Account records, all with the same name, and that name does not currently exist in the database. Will it allow Insertion ?

    • @JShorts511
      @JShorts511 2 หลายเดือนก่อน

      The following code will not allow
      /*Trigger Scenario:
      Write a trigger to prevent duplicate accounts based on name whenever an Account is inserted or updated.
      Scenario is to validate records before they are saved to database. so we use before trigger.
      context variables to access runtime contexts are Trigger.isInsert and Trigger.isUpdate*/
      trigger AccountTrigger on Account(before insert,before update){
      //set to collect Account Name from triggering records.
      List accNames=new List();
      //accessing run time context
      if(Trigger.isBefore){
      if(Trigger.isInsert){
      //iterating over triggering records
      for(Account acc:Trigger.new){
      accNames.add(acc.Name);
      }
      }
      if(Trigger.isUpdate){
      //iterating over triggering records
      for(Account acc:Trigger.new){
      //checking whether the account's Name is changed or not
      if(acc.Name != Trigger.oldMap.get(acc.Id).Name){
      accNames.add(acc.Name);
      }
      }
      }
      }
      List accList=[SELECT Id,Name FROM Account WHERE Name IN:accNames];
      set accNameSetToCheckDups=new set();
      //Map to get number of accounts with same name
      Map accNamesCountwithName=new Map();
      //iterating over accNames
      if(!accNames.isEmpty()){
      for(String acctName:accNames){
      if(!accNamesCountwithName.containsKey(acctName)){
      accNamesCountwithName.put(acctName,0);
      }else {
      Integer count=accNamesCountwithName.get(acctName)+1;
      accNamesCountwithName.put(acctName,count);
      }

      }
      }
      //iterating over accList to collect existing names
      if(!accList.isEmpty()){
      for(Account acc:accList){
      accNameSetToCheckDups.add(acc.Name);
      }
      }
      //iterating over Triggering records to prevent duplicates
      if(!accNameSetToCheckDups.isEmpty() || accNamesCountwithName.keySet() !=null ){
      //if triggering records has the same name more than one (If we are inserting /updating with same name at a time)
      for(Account acc:Trigger.new){
      if(accNamesCountwithName.get(acc.Name)>1 || accNameSetToCheckDups.contains(acc.Name)){
      acc.addError('Account already exists with the same name');
      }
      }
      }
      }

    • @naveenyalamala
      @naveenyalamala 2 หลายเดือนก่อน

      @@JShorts511 thank you

  • @rahulkumbhare5454
    @rahulkumbhare5454 ปีที่แล้ว

    Hi SFDC Ninja, can't we simply check the size of accList and determine duplicate account name present or not? The accList will have values only if the Accounts with the given names are already present. So, if the size is more than 0, it means we already have accounts in the database with name which are being inserted. Please correct if this understanding is wrong. Thanks

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว

      Hi Rahul , see Checking the size of accNames instead of accList may not be suitable for bulk records. also Without querying the accList, you won't have access to the actual existing accounts with duplicate names. This means you cannot perform any specific actions or validations on those existing accounts. It may limit your ability to handle duplicates effectively or implement customized logic based on the existing account records.

  • @prasadpj8577
    @prasadpj8577 ปีที่แล้ว +1

    This will fail for update operation when we click edit and save without even changing name

    • @naveenyalamala
      @naveenyalamala 2 หลายเดือนก่อน

      public static void preventDuplicateRecord(List accList){
      // Collect unique account names (normalized to lowercase)
      Set newAccNames = new Set();

      for (Account acc : accList) {
      if (acc.Name != null) {
      newAccNames.add(acc.Name.toLowerCase());
      }
      }
      // Query existing accounts with names in the set
      List existingAccounts = [
      SELECT Id, Name
      FROM Account
      WHERE Name IN :newAccNames
      ];

      // Collect existing account names and their IDs
      Set existingAccNames = new Set();
      Map existingNameToIdMap = new Map();
      for (Account acc : existingAccounts) {
      existingAccNames.add(acc.Name.toLowerCase());
      existingNameToIdMap.put(acc.Name.toLowerCase(), acc.Id);
      }

      // Flag duplicate records
      for (Account acc : accList) {
      if (acc.Name != null) {
      String normalizedName = acc.Name.toLowerCase();
      // Check if the name exists and if it's not the same as the current record
      if (existingAccNames.contains(acc.Name.toLowerCase()) &&
      !existingNameToIdMap.get(acc.Name.toLowerCase()).equals(acc.Id)) {
      acc.addError('Duplicate Account Name detected: ' + acc.Name);
      }
      }
      }
      }

  • @prasadpj8577
    @prasadpj8577 ปีที่แล้ว

    Please upload a scenario to avoid trigger using Map

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว

      Hi Prasad sure i will try to create a video on it .

  • @praveenbuddi190
    @praveenbuddi190 ปีที่แล้ว

    bro, small suggetion increse font size.

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว

      sure bro and thank you for suggestion

  • @ramadevikantamani3057
    @ramadevikantamani3057 ปีที่แล้ว

    Scenario will fail when we update other fields in the account other than name .

    • @sfdcninjas
      @sfdcninjas  ปีที่แล้ว

      Hi , In this scenario I have explained trigger to prevent duplication of account record based only on Name field you can add other fields to prevent duplication.
      Thank you

  • @rohantelang1817
    @rohantelang1817 10 หลายเดือนก่อน

    In this solution, there is many "for loops".can any one provide solution by reducing "for loops"?

    • @lokeshv8999
      @lokeshv8999 9 หลายเดือนก่อน

      trigger CandidateTrigger on Account(Before insert,Before Update){
      if(trigger.isbefore && (trigger.isinsert ||trigger.isUpdate ){
      listaccrecord=[select id,name from account];
      for(Account accnew:Trigger.new){
      for(Account accold:accrecord){
      if(accnew.name==accold.name){
      accnew.name.adderror('Duplicate Name cannot be entered again');
      }
      }
      }
      }
      }

    • @SathishKumar-ok6tu
      @SathishKumar-ok6tu 8 หลายเดือนก่อน

      @@lokeshv8999 List accrecord = [select id,name from account]; As per Salesforce Governor Limits, SOQL will return maximum 50K records. This will fail if our org contains more than 50K account records. Also, this code contains nested for loop which will affect performance.

  • @praveenbuddi190
    @praveenbuddi190 ปีที่แล้ว

    goto VScode settings--- settings- search for Font -- default is 14- to increase- 20-24 font size...

  • @sfdcakshul
    @sfdcakshul ปีที่แล้ว

    Informative 👍

  • @deboleenadutta1448
    @deboleenadutta1448 6 หลายเดือนก่อน

    what is the peoblem with the simple solution given below.. if anybody has idea let me know
    trigger PreventDupl on Account(before Insert , before delete){

    if(trigger.isBefore && trigger.isDelete){

    for(account acc : trigger.new){

    integer countedRec = [select count(id) from Account where name = acc.name];

    if(countedRec > 0){

    acc.addError('Already an account is existing with the provided name');


    }

    }

    }


    }

    • @rupesh-patil011
      @rupesh-patil011 5 หลายเดือนก่อน

      @deboleenadutta1448 You are doing SOQL inside for loop. It will hit the governor limit and before delete is not required.

    • @deboleenadutta1448
      @deboleenadutta1448 5 หลายเดือนก่อน

      @@rupesh-patil011 thanks … yes before delete is my mistake…

  • @praveennanda7521
    @praveennanda7521 5 หลายเดือนก่อน

    trigger AccountTrigger on Account(before insert, before update)
    {
    if(trigger.isbefore && (trigger.isinsert || trigger.isupdate))
    {
    for(Account acc :trigger.new)
    {
    Integer accountCount = [Select count() from Account where Name =: acc.Name];
    if(accountCount>0)
    acc.Name.addError('Please enter the last name as uniquly');
    }
    }

    }

    • @ShikhaKanaujia-k7d
      @ShikhaKanaujia-k7d 5 หลายเดือนก่อน

      avoid using SOQL inside for loop

  • @BusraYildiz-t3u
    @BusraYildiz-t3u 5 หลายเดือนก่อน +1

    trigger ApexTrigger6 on Account (before insert,before Update) {

    Set Names = new Set();
    If(Trigger.isBefore){
    For(Account acc: Trigger.new){
    if(trigger.isInsert|| acc.Name!=trigger.oldMap.get(acc.id).Name){
    Names.add(acc.Name);
    }
    }


    }


    List ExistingName = New List();

    For(Account acc:[Select Name, Id From Account Where Name In:Names]){
    ExistingName.add(acc.Name);
    }



    For(Account acc: trigger.new){
    if(ExistingName.Contains(acc.name))
    acc.Name.addError('duplicate');
    }

    }
    here is another approach