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
Glen.ax1034Glen.ax1034 

Non-selective query against large object type (more than 100000 rows).

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger EscalateCase caused an unexpected exception, contact your administrator: EscalateCase: execution of BeforeInsert caused by: System.QueryException: Non-selective query against large object type (more than 100000 rows). Consider 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): Trigger.EscalateCase: line 76, column 1

 

It is erroring on line:

List<Case> cCaseTypes = [SELECT Status, Id FROM Case where Status='Escalation Hold' AND ParentId =:escalatedcase.id LIMIT 10];


 

trigger EscalateCase on Case (before update, before insert) {
//MAP record type ID's to record type names.
        List<RecordType> rTypes = [select id,name from RecordType where SobjectType='Case'];    //pull recordtype Id's and record type names from recordtypes where the sobject is contract
           
        MAP<Id , String> maprtID_rtName = new MAP<ID , String>();  //map record type ID's to record type names.
        for(RecordType rTypeObj :  rTypes)
        {
            maprtID_rtName.put(rTypeObj.id , rTypeObj.Name); //for all recordtypes... log id's and record type names.
        }
//MAP Record type names to record type ID's
        List<RecordType> rTypesCases = [select name,id from RecordType where SobjectType='Case'];    //pull recordtype Id's and record type names from recordtypes where the sobject is contract
        
        MAP<String, ID> maprtName_rtIDCases = new MAP<String, ID>();  //map record type ID's to record type names.
        for(RecordType rTypeObj :  rTypesCases)
        {
            maprtName_rtIDCases.put(rTypeObj.Name, rTypeObj.id); //for all recordtypes... log id's and record type names.
        }
        
//MAP Case User Owner/Queue Names to reference ID's
        List<User> uTypesUsers = [select name,id from User];    //pull recordtype Id's and record type names from recordtypes where the sobject is contract
        
        MAP<String, ID> maprtName_rtIDUsers = new MAP<String, ID>();  //map record type ID's to record type names.
        for(User uTypeObj :  uTypesUsers)
        {
            maprtName_rtIDUsers.put(uTypeObj.Name, uTypeObj.id); //for all recordtypes... log id's and record type names.
        }
        
//MAP Case Group Owner/Queue Names to reference ID's
        List<Group> gTypesGroups = [select name,id from Group where Type='Queue'];    //pull recordtype Id's and record type names from recordtypes where the sobject is contract
        
        MAP<String, ID> maprtName_rtIDGroups = new MAP<String, ID>();  //map record type ID's to record type names.
        for(Group gTypeObj :  gTypesGroups)
        {
            maprtName_rtIDGroups.put(gTypeObj.Name, gTypeObj.id); //for all recordtypes... log id's and record type names.
        }
    
////map for temporary return from escalation
    
    

//bulk cases for upsert
      List<Case> Cases = new List<Case>();
      List<CaseComment> ccomments = new List<CaseComment>();
      List<CaseComment> dcomments = new List<CaseComment>();
      List<CaseComment> pcomments = new List<CaseComment>();
      boolean escalated = false;
      boolean bccomments = false;
      boolean bdcomments = false;
      boolean bpcomments = false;
      MAP<ID, ID> mapescalate_add = new MAP<ID, ID>();

//lets have a look at all the trigger(s)
for (Case escalatedcase:Trigger.new){

escalated = false;    
    
//trying to close the parent case while children are still open   
      if (escalatedcase.Status=='Closed') { //trying to close the parent case while children are still open
            integer close = [Select count() from Case where ParentId = :escalatedcase.id and isClosed != true];
            if (close > 0) {
                  escalatedcase.addError('There are still Child Cases Open - Please close and try again!'); //in your face!
            }
      }
//END trying to close the parent case while children are still open


      if(maprtID_rtName.get(escalatedcase.RecordTypeId) == 'National Client Service') {
            
                  if(escalatedcase.ParentId == null) {
                      
                        if(escalatedcase.Status != 'Escalated' && escalatedcase.Status != 'Returned from Escalation' && escalatedcase.Status != 'Closed') {
                              //if any escalatedcase childcase has a status 'Escalation Hold' then pass the comments back to that case and put this case on status escalated and put that status as new
                              // then if not, proceed with the escalation group stuff
                            
                            //List<Case> cCaseTypes = [SELECT Status, Id FROM Case where ParentId =:escalatedcase.id LIMIT 10];
                            List<Case> cCaseTypes = [SELECT Status, Id FROM Case where Status='Escalation Hold' AND ParentId =:escalatedcase.id LIMIT 10];
                            for(Case eCase : cCaseTypes) {
                                If (eCase.Status == 'Escalation Hold') {
                                                
                                      Case CaseAdd = new Case(Id = eCase.id);
                                      CaseAdd.Status = 'New';
                                      CaseAdd.Escalation_Completion_Date__c = System.now();
                                      Cases.add(CaseAdd);
                                    
                                    
                                            List<CaseComment> comments = [Select c.Id, c.ParentId, c.IsPublished, c.CommentBody, c.CreatedById, c.CreatedDate, c.SystemModstamp, c.LastModifiedDate, c.LastModifiedById, c.IsDeleted from CaseComment c where c.ParentId = :escalatedcase.Id];
            
                                            for(CaseComment oldcomment :  comments) {
                                                CaseComment newcomment = new CaseComment();
                                                dcomments.add(oldcomment);
                                                bdcomments = true;
                                                newcomment.ParentId = escalatedcase.ParentId;
                                                newcomment.IsPublished = oldcomment.IsPublished;
                                                newcomment.CommentBody = oldcomment.CommentBody + escalatedcase.OwnerId + escalatedcase.Owner.Name;
                                                //Do I want to remove duplicates?
                                                //if (newcomment.CommentBody.substring(0,6) == 'Parent') { } else {
                                                    pcomments.add(newcomment);  
                                                    bpcomments = true;
                                                //}
                                            }
             
                                        
                                        
                                        escalated = true;
                                }
                            }
                            
                            

 


Starz26Starz26

There error states it all.

 

Since you are filtering against an object that potentially holds ALOT of data you get this error as you are not being selective.

 

Using the ParentID is not selective enough because it could potentially query to many rows regardless on your return of only 10. This is not to say you actually have that many rows, but rather the potential to have many rows.

 

So, consider the items in the following link to resolve your issue:

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_SOQL_VLSQ.htm

Glen.ax1034Glen.ax1034

basically I am trying to select all cases that would be child cases of a parent case.

 

I am failing to do so, something that would be fairly easy, how would you approach it?

Starz26Starz26

Maybe get the date the parent case was created and use that date in the SOQL for the child to narrow it down to only case created between those dates.

Glen.ax1034Glen.ax1034

new code, same error:

 

                           List<Case> cCaseTypes = [SELECT Status, Id FROM Case where Status='Escalation Hold' AND ParentId =:escalatedcase.id AND CreatedDate > :escalatedcase.CreatedDate LIMIT 10];

 

 

Starz26Starz26

Remove:

 

Status='Escalation Hold'

 

from the criteria and then check that value after getting the records. Criteria are evaluated individually do this may be causing your issue.

Glen.ax1034Glen.ax1034

still failing. i thought that was going to solve it.

 

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger EscalateCase caused an unexpected exception, contact your administrator: EscalateCase: execution of BeforeInsert caused by: System.QueryException: Non-selective query against large object type (more than 100000 rows). Consider 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): Trigger.EscalateCase: line 76, column 1

 

                            List<Case> cCaseTypes = [SELECT Status, Id FROM Case where ParentId =:escalatedcase.id AND CreatedDate > :escalatedcase.CreatedDate LIMIT 10];

 


Starz26Starz26

I am out of ideas.

 

I do not even have parentid on case in my org so I cannot test

Noam DganiNoam Dgani

Try adjusting your code the following way:

 

instead of - 

List<Case> cCaseTypes = [SELECT Status, Id FROM Case where Status='Escalation Hold' AND ParentId =:escalatedcase.id LIMIT 10];
for(Case eCase : cCaseTypes)

{

your logic

}

 

Do - 

for(Case eCase: [SELECT Status, Id FROM Case where Status='Escalation Hold' AND ParentId=:escalatedcase.id LIMIT 10])

{

your logic

}