+ Start a Discussion

Too many SOQL queries: 101, @future

I am calling the following class from my trigger after update on Account.  When I update more that 50 records I get the error. I need to update 30000 records.

I am getting the Too many SOQL queries: 101 error.

Can someone help me how I can batch this code.  The trigger and code are working fine.

I updated Upto 45 records without errors. How can I batch this so I can update more records at a time.


  public class createMycustomAcc {

  public static void Acctsetsfor(String[] acIds){
   List<customobject__c> finalLst new List<customobject__c>()
     List<Account> ac = [select Id, Name, Market_name__c from Account where market_name__c != null AND Id IN :acIDs];

 for(Account a :ac){
     String RecType = a.RecordTypeId;
     String Rating = a.Rating__c;
     String SameId = a.Id;
     String MarketName = a.market_name__c;

     qrystr= 'select name, Id, Rating__c from Account WHERE RecordTypeId = \'' + RecType + '\' AND Id != \'' + SameId +'\' AND market_name__c = \'' + marketName + '\'  custom_id__c != Null LIMIT 150';
      Htlaccts = Database.query(qrystr);  // this line is causing errors
     if(Htlaccts.size() >0{
       for((Integer i = 0; i < Htlaccts.size();i++){
          // more conditions if true
          //build a list of custom object
          // if false i = Htlaccts.size()
          customobject__c cobj = new customobject__c(Account__c = a.id, relatedto__c =Htlaccts[i].id);

     if(finalLst.size() > 0 ) insert finalLst;

Message Edited by Umapen on 04-17-2009 08:06 AM

That's a tricky one.  First, mostly for the sake of readability, you don't need to build it dynamically like that.  You could just do:



Account Htlaccts = [select name, Id, Rating__c from Account WHERE RecordTypeId = :RecType AND Id != :SameId AND market_name__c = :marketName AND custom_id__c != Null LIMIT 150'];


But that won't solve the problem.  Doing this query in the loop is the problem.  You're expecting that all these accounts will have different record types and market names, right?  If not you could factor this query out of the loop by making a list of the IDs you got from List<Account> ac, and then getting the record type and market name of the first account in the list, and then:


Account Htlaccts = [select name, Id, Rating__c from Account WHERE RecordTypeId = :RecType AND Id != :SameId AND market_name__c = :marketName AND custom_id__c != Null WHERE Id NOT IN :acIds LIMIT 150'];


But if those rectypes are going to be different then I can't think of a way you could avoid doing that in the loop.




Thanks for the quick response.  I have 3 more additional conditions in my query where I am checking for  " != null". Therefore, my query is taking too long and I got  the following error

 Time limit exceeded
Your request exceeded the time limit for processing.

When I changed the query to Database.query(string) the query time gone down drastically.

I have three record types and many marketNames.


Thanks again for the response. the @future at the beginning seem useless.



The @future isn't useless -- if you're calling it from a trigger, that will cause this method to be run asynchronously, which relaxes the limits considerably.  If you were trying to do this straight up in a trigger without the @future it would die when you updated 19 accounts (or less if you have other triggers running queries also).