+ Start a Discussion
Keaton KleinKeaton Klein 

Too many SQL queries

I have the following code which works for the opportunity object, but when i duplicated the code for some other objects i am getting an error stating that i have too many SQL queries.  
Set<Id> OpportunityIds = new Set<Id>();
    Map<Id,Opportunity> mapOpportunityLogWithId = new Map<Id,Opportunity>();
    Map<Id,Opportunity> mapOpportunityLogToUpdate = new Map<Id,Opportunity>();    

    for(Opportunity a:[SELECT Description FROM Opportunity WHERE ID IN:OpportunityIds]){
        mapOpportunityLogWithId.put(a.Id,a);
    }
How do i bulkify the for loop, making it more efficient with less SQL queries?  I attempted something like the code below but on line 6 i get a problem stating "Initial term of field expression must be a concrete SObject: List"
Set<Id> OpportunityIds = new Set<Id>();
    List<Opportunity> mapOpportunityLogWithId = new List<Opportunity>();
    Map<Id,Opportunity> mapOpportunityLogToUpdate = new Map<Id,Opportunity>();    

    for(Opportunity[] a:[SELECT Description FROM Opportunity WHERE ID IN:OpportunityIds]){
        mapOpportunityLogWithId.put(a.Id,a);
    }

 
KaranrajKaranraj
The too many soql query exception is not only from that trigger, it will counted based on excution context. Check other trigger code also.

This error System.LimitException: Too many SOQL queries: 101is due to the fact, you are hitting on governor limit. The governor limit that says we can run total 100 SOQL queries in a context and you are hitting the limit.
 
All the triggers fired will be counted in a single context or call. We need to ensure that total number of SOQL fired should be less than 100.
In order to by pass this, you need to change your code in such a way that SOQL fired must be less than 100 or if you need to change the context then you can use @future annotation which will run the code asynchronously.
 
You need to make sure that the SOQL query you are using should not be inside the for loop.

There are certain best practices which you would have to follow to avoid this error (to avoid hitting governor limit).

1. http://wiki.developerforce.com/page/Best_Practice:_Avoid_SOQL_Queries_Inside_FOR_Loops

2. http://salesforcedeveloperblog.blogspot.com/2011/05/best-practices-of-triggers.html

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

4. http://wiki.developerforce.com/page/Apex_Code_Best_Practices (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_bestpract.htm)
 
If you follow the above practices, the error will stop. Moreover there is no way wherein we in Salesforce can increase the
governor limit or can stop it so best practices need to be followed
 
Benoy VmBenoy Vm

I would initialize the map as follows and if you want the list of oppotunities then use map.values(). See below. 

Set<Id> OpportunityIds = new Set<Id>();
List<Opportunity> mapOpportunityLogWithId = new List<Opportunity>();
Map<Id,Opportunity> mapOpportunityLogToUpdate = new Map<Id,Opportunity>([SELECT Description FROM Opportunity WHERE ID IN:OpportunityIds]);
mapOpportunityLogWithId = mapOpportunityLogToUpdate.values();