+ Start a Discussion
Blake TanonBlake Tanon 

Trigger SOQL Limit on Recurring Tasks

I ran into this error for the first time today with the below trigger, it only happens when recurring tasks are created.  Apex trigger ContactCallBulk caused an unexpected exception, contact your administrator: ContactCallBulk: System.LimitException: Too many SOQL queries: 101.  Any ideas to make this trigger only run on non-recurring tasks or another fix?  

 

I tried to add an if statement to run if IsRecurrence == FALSE and then not true but that didn't work.

 

trigger ContactCallBulk on Task (after insert, after update) {
//Trigger works with bulk apex
//Updates total number of calls on contact
    
    //Get current task Id
    for (Task tn:Trigger.new){
    if(tn.IsRecurrence <> TRUE){
        System.debug('id is: '+tn.id);
        System.debug('subject is: ' +tn.Subject);
    //Map contact related to WhoId
    Map<Id,Contact> parents = new Map<Id,Contact>([SELECT Id FROM Contact WHERE id =:tn.whoid LIMIT 1]);
    
    
    if(Trigger.new<>null)
        for(Task t:Trigger.new){
        if(t.Status == 'Completed'){
        System.debug('id is: '+t.id);
        System.debug('subject is: ' +t.Subject);
            if(t.WhoId<>null)
                parents.put(t.WhoId,new Contact(id=t.WhoId));
        }}
        
    if(Trigger.old<>null)
        for(Task t:Trigger.old){
        if(t.Status == 'Completed'){
        System.debug('id is: '+t.id);
        System.debug('subject is: ' +t.Subject);
            if(t.WhoId<>null)      
                parents.put(t.WhoId,new Contact(id=t.WhoId));
        }}
    update parents.values();
    
    }}
}

 

Suresh RaghuramSuresh Raghuram

Try to avoid writing Soql quires in for loop

In ur case the below line of code write it out of the for loop

Map<Id,Contact> parents = new Map<Id,Contact>([SELECT Id FROM Contact WHERE id =:tn.whoid LIMIT 1]);

Blake TanonBlake Tanon

How do I get the ID for the task if it's before the for and keep it working with bulk?

Andrew WilkinsonAndrew Wilkinson

I don't see where you are updating any contact values so I am assuming a contact trigger fires based on the update. Anyway the below code does what you need it to do. I added some notes since I do not see why you are populating the Map with a query if you never use any getter methods. You can just instantiate the map and put the values in. I added a note to show you. It would accomplish the same thing since you are not using any get methods. 

 

trigger ContactCallBulk on Task (after insert, after update) {
//Trigger works with bulk apex
//Updates total number of calls on contact

    //Put the ids in a set and use the set in a query to populate the map
    Set<Id> tnWhoIds = new Set<Id>();
    for (Task t : Trigger.new){
        tnWhoIds.add(t.whoId);
    }
    
    //this could become Map<Id,Contact> parents = new Map<Id,Contact>(); since in this trigger you are 
    //putting values into your map. I don't see the point in the query but here it is.
    Map<Id,Contact> parents = new Map<Id,Contact>([SELECT Id FROM Contact WHERE id IN :tnWhoIds LIMIT 1]);
    
    //Get current task Id
    for (Task tn:Trigger.new){
    if(tn.IsRecurrence <> TRUE){
        System.debug('id is: '+tn.id);
        System.debug('subject is: ' +tn.Subject);
    
    
    
    if(Trigger.new<>null)
        for(Task t:Trigger.new){
        if(t.Status == 'Completed'){
        System.debug('id is: '+t.id);
        System.debug('subject is: ' +t.Subject);
            if(t.WhoId<>null)
                parents.put(t.WhoId,new Contact(id=t.WhoId));
        }}
        
    if(Trigger.old<>null)
        for(Task t:Trigger.old){
        if(t.Status == 'Completed'){
        System.debug('id is: '+t.id);
        System.debug('subject is: ' +t.Subject);
            if(t.WhoId<>null)      
                parents.put(t.WhoId,new Contact(id=t.WhoId));
        }}
    update parents.values();
    
    }}
}