+ Start a Discussion
wcwill978wcwill978 

Too many script statements: 200001 Error

Hi I have a simple APEX class that updates accounts with old opportunities to inactive. The class is Schedulable and runs and works as it should. I am having a problem when I run the test class and trying to deploy it into Prod. The test class is failing with the following error message:

 

System.LimitException: jigsaw_clean:Too many script statements: 200001

 

Here is my class:

 

global class AcctInactiveUpdate implements Schedulable 
{
 global void execute(SchedulableContext sc) 
 {
 
 Map<id,account> aMap = new Map<id,account>([Select Id, Type, Last_Won_Opportunity__c, RecordTypeId FROM Account 
                                                    WHERE RecordTypeId != '012300000000Dk1'
                                                    AND Type = 'Active'
                                                    Limit 8000]);
                                                    

List<account> accList = aMap.values() ;
 
Set<id> accIds = aMap.keySet() ;


           for(Account acct: accList)  
           {
            //Get all Active Accounts where the last won deal was over 2yrs ago from above list
            if(acct.Last_Won_Opportunity__c < System.Today().addYears(-2)) 
             
              {
               acct.Type = 'Inactive'; 
               acct.Last_Set_to_Inactive__c = System.today(); 
              }
          }
          
          update accList;
   }
}


 

Here is the Test class I'm using which gives me 100% code coverage, but fails due to the governor limit:

 

@istest

class AcctInactiveUpdateTestClass {

public static testMethod void testschedule() {

        Test.StartTest();
            AcctInactiveUpdate sh = new AcctInactiveUpdate();
                String sch = '0 0 5 * * ?';
                system.schedule('Schedule TEST', sch, sh);
        Test.stopTest();
       
        }
    }

 

Can someone please help me what can I do to not hit the script statement limit? I added a limit of 8K accounts on the class to see if that helps and still no avail.

kiranmutturukiranmutturu

use batchapex and schdule that class to avoid all the governor limits.. 

wcwill978wcwill978

Hi Kiran,

 

I wrote a new batch job and a schedulable job that calls out the batch job. When the schedulable job runs nothing happens. I was able to update the records before when I had all the logic in the same class now it is not updating. Am i writting this correct:

 

Here is the batch apex and below that is the schedulable class im using to schedule the job:

 

Thank you for your help.

 

 

global class AcctInactiveBatch implements Database.Batchable<SObject>{

String Query;

global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator(query);
   }
   
global void execute(Database.BatchableContext BC, List<sObject> scope){
   List<Account> updateacct = new List<Account>([SELECT ID, Type, Last_Won_Opportunity__c, RecordTypeId FROM Account 
                                                    WHERE RecordTypeId != '012300000000Dk1'
                                                    AND Type = 'Active']);
        
           for(sObject s : scope) {Account acct = (Account)s;

            //Get all Active Accounts where the last won deal was over 2yrs ago from above list
            if(acct.Last_Won_Opportunity__c < System.Today().addYears(-2)) 
             
              {
               /*
               Set the accounts that meet above criteria to Inactive and
               Set todays date so I can track when the acct was set to inactive
               */
               acct.Type = 'Inactive'; 
               acct.Last_Set_to_Inactive__c = System.today(); 
               updateacct.add(acct);
              }
        }

update updateacct;
              
}
              
global void finish(Database.BatchableContext BC){
            
global class ScheduleAcctInactiveBatch implements schedulable
{
    global void execute(SchedulableContext sc)
    {
    AcctInactiveBatch b = new AcctInactiveBatch();
      database.executebatch(b);
    }



 

 

Juan SpagnoliJuan Spagnoli

You batch process is wrong:

 

 

global Iterable<sObject> start(Database.BatchableContext BC){

 

return [SELECT ID, Type, Last_Won_Opportunity__c, RecordTypeId FROM Account WHERE RecordTypeId != '012300000000Dk1' AND Type = 'Active']

}

 

global void execute(Database.BatchableContext BC, List<Account> scope){

    List<Account> accountToUpdate = new List<Account>();

    for(Account acc: scope){

          if(acct.Last_Won_Opportunity__c < System.Today().addYears(-2)) {

                  acct.Type = 'Inactive'; 

                  acct.Last_Set_to_Inactive__c = System.today(); 

                  accountToUpdate.add(acct);

          }

    }

   update accountToUpdate;

}

 

 

And when you start de batch use:

 

database.executebatch(b,200); //the execute method will take batch of 200 objects

 

 

 

wcwill978wcwill978

Thank you Juan.

 

I got it to work in my dev org and it updated the correct records. I moved it to my full sandbox where we have all the data and I have also added a test class within the batch job and now I am getting this error:

 

System.UnexpectedException: No more than one executeBatch can be called from within a testmethod. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.

 

How can I get my code coverage up and pass this error? Here is the updated class:

 

global class AcctInactiveBatch implements Database.Batchable<SObject>{

global Iterable<sObject> start(Database.BatchableContext BC){

return ([SELECT ID, Type, Last_Won_Opportunity__c, RecordTypeId FROM Account
                WHERE RecordTypeId != '012300000000Dk1' 
                AND Type = 'Active']);

}

global void execute(Database.BatchableContext BC, List<Account> scope){

    List<Account> accountToUpdate = new List<Account>();

    for(Account acct: scope){

          if(acct.Last_Won_Opportunity__c < System.Today().addYears(-2)) {

                  acct.Type = 'Inactive';
                  acct.Last_Set_to_Inactive__c = System.today();
                  accountToUpdate.add(acct);

          }
    }
   update accountToUpdate;
}
              
global void finish(Database.BatchableContext BC){
             
   }
   
   static testmethod void testbatchjob()
    {
        test.startTest();
        
        Account newrec=new Account(Name='test');
        insert newrec;
        AcctInactiveBatch it = new AcctInactiveBatch();
        database.executebatch(it);
        test.stopTest();
        
    }

}



Juan SpagnoliJuan Spagnoli

Yes, that is because in test method you have to limit the batch to 1.

 

 

static testmethod void testbatchjob()
    {
        test.startTest();
        
        Account newrec=new Account(Name='test');
        insert newrec;
        AcctInactiveBatch it = new AcctInactiveBatch();
        database.executebatch(it,1);
        test.stopTest();
}

 

 Don't forget to limit the execute method to 200 records when you start your batch in production or sandbox. I recommend you to read "Using Batch Apex" from Apex Code Developer's Guide 

 

Good luck.

Juan SpagnoliJuan Spagnoli

Another thing... i recommend you to use:

 

RecordType.DeveloperName != 'TheNameOfRecordType'

 

That it works in any enviroment without changing the query (Prod, Sandbox, Dev) 

 

wcwill978wcwill978

Thanks for the pointer I appreciate it Juan. I had that problem when I moved it from dev to test sandbox. i added the limit and am now able to get rid of the system exception error, but only get 72% test coverage. For some reason the test class is not covering these three lines of code:

 

acct.Type = 'Inactive';

acct.Last_Set_to_Inactive__c = System.today();

accountToUpdate.add(acct);

 

I even  modified the newrec being inserted to match the slect statement and still does not cover those three lines

Juan SpagnoliJuan Spagnoli

Maybe is because in your test you are inserting an Account's record without setting the value for "Last_Won_Opportunity__c".

 

 

wcwill978wcwill978

Also tried that by setting it to:

Im trying to look at other alternatives now to see if i can get it above 75% test coverage, any other ideas?? thank you

 

static testmethod void testbatchjob()
    {
        test.startTest();
        Account newrec=new Account(Name='test', Type = 'Active', RecordTypeId = '01280000000Bc77', Last_Won_Opportunity__c = System.Today().addYears(-3));
        insert newrec;
        system.debug('After insert new rec' + newrec);
        AcctInactiveBatch testbc = new AcctInactiveBatch();
        database.executebatch(testbc,1);
        test.stopTest();
    }
Juan SpagnoliJuan Spagnoli

well... you can put your code inside a method and then execute that method in an explicit way in your test.