0

I'm getting an error message when I update my Contact name:

CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateCallsonContactNameChange: execution of AfterUpdate caused by: System.QueryException: Non-selective query against large object type (more than 100000 rows).

Considered an indexed filter or contact salesforce.com about custom indexing. Even if a field is indexed a filter might still not be selective when:

  1. The filter value includes null (for instance binding with a list that contains null)
  2. Data skew exists whereby the number of matching rows is very large (for instance, filtering for a particular foreign key value that occurs many times)

Second error:

Class.updatePhysiciansonContactNameChange.changeName: line 9, column 1 Trigger.UpdateCallsonContactNameChange: line 12, column 1: []"].

I'm giving my Trigger and class to analyze:

trigger UpdateCallsonContactNameChange on Contact (after update) {
    if(updatePhysiciansNameonContactNameChange.RecursiveFlag)   
    {     
        updatePhysiciansNameonContactNameChange
           .changeName(Trigger.NewMap.keyset(),Trigger.new,Trigger.oldMap);        
    }
}

In the class the Physicianid and Fellowid__c are 2 lookup fields to the Contact.

Below is my class:

global class updatePhysiciansonContactNameChange
{
    public static Boolean RecursiveFlag = true; 
    public static void changeName(Set<Id> ids, List<Contact> conlist, 
        Map<Id, Contact> mapcontact)
    { 
        List<Call__c> listcall = [select Id,Physicians__c,Physicianid__c,
            Fellowid__c,Fellow__c from call__c 
            where Physicianid__c in :Ids or Fellowid__c In :ids];
        List<Call__c> updateCalls = new List<Call__c>();

        for (Contact con : conlist ) {             
            Contact oldcon= mapcontact.get(con.Id); 

            if(con.FirstName != oldcon.FirstName || con.LastName != oldcon.LastName) {    
                for (Call__c casrecord:listcall){            
                    if(casrecord.Physicianid__c == con.id)
                    {                       
                        casrecord.Physicians__c = con.FirstName + ' ' + con.LastName;
                    }
                    else if(casrecord.Fellowid__c == con.id)
                    {
                        casrecord.Fellow__c = con.FirstName + ' ' + con.LastName;
                    }

                    updateCalls.add(casrecord);           
                }
             }

        } 

        RecursiveFlag = false;
        update updateCalls;
  }
}
0

WHERE IN can be pretty expensive and you have two. I would split your query for calls into two querys and see if that helps if you have the room in terms of number of queries. One where you query for Physicianid__c IN :Ids and the second query for FellowId__c IN :Ids.

If there would ever be a case where both parts of your OR would be true take your queries results and put them into sets so your update list doesn't have multiples of the same record.

Set<Call__c> callSet.addAll([SELECT .... WHERE PhysicianId__c IN :Ids]);
callSet.addAll([SELECT .... WHERE FellowId__c IN :Ids]);

Also, I don't know what your other requirements are but in your code you are setting a text field on Call__c that is a concatenation of Contact.FirstName and Contact.LastName. This could be achieved through a formula field for both Physician and Fellow

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.