+ Start a Discussion
Rafael Suarez 14Rafael Suarez 14 

Can you write up a class and batch it from an execute anonymous block?

Is it possible to use the batchable class in an anonymous block?
I'm attempting to update to a few hundred accounts from within the Execute Anonymous environment, but because of the existing Apex, Im getting "Too many SOQL queries: 50001".
So I attempted the following code (still within an  anonymous block) and it will come back with 

"Execute Anonymous Error
Line: 13, Column: 14
Global type must be contained inside of a global class"

I think the developer console doesn't like global classes...    Does it ?
Do I absolutely need a global modifier to use the SFDC batchable classes ?
Advise will be appreciated

This is the actual code:  
global class SICS implements Database.Batchable<Account>{
   global final String Query;
   string q = 'Select Id, CMSIC8A__c, Temp_BadCMSIC__c from Account' +
               'where Temp_BadCMSIC__c != NULL ';
    
  global UpdateAccountFields(String q){ Query=q;}

  global Database.querylocator start(Database.BatchableContext BC){
            return Database.getQueryLocator(query);}
    
 global void execute(Database.BatchableContext BC, List<Account> scope){
   
LIST<Account> SIC2Up  = [Select Id, CMSIC8A__c, Temp_BadCMSIC__c from Account where Temp_BadCMSIC__c != ''];
List <Account> Acc2Up = new List<Account>();
    for(Account acc : scope){
    IF(acc.Temp_BadCMSIC__c != NULL){
       acc.CMSIC8A__c = acc.Temp_BadCMSIC__c;
    }
    Acc2Up.add(acc);
}
Update Acc2Up;
}
}

// SICS obj = new SICS(); 
Id batchJobId = Database.executeBatch(new SICS(),200);
Thanks
RSM
 
Rafael Suarez 14Rafael Suarez 14
errata:  I meant to write:
"The Execute Anonymous tool doesnt like global classes"
Charisse de BelenCharisse de Belen
No, you can't implement a global class in Anonymous Apex. You should go ahead and actually create the class and then execute the batch from Anonymous Apex as described here: https://help.salesforce.com/articleView?id=000171199&language=en_US&type=1
Rafael Suarez 14Rafael Suarez 14
Thanks for your advise Charisse.  But what about public classes, and why can't we use them for batching ? I read that same link, and it does not explicitly state your top-level class needs to be global.  
Amit Chaudhary 8Amit Chaudhary 8
Please save the batch job like below
global class SICS implements Database.Batchable<Account>{
	
	global final String Query;
	string q = 'Select Id, CMSIC8A__c, Temp_BadCMSIC__c from Account' +
				   'where Temp_BadCMSIC__c != NULL ';

	global SICS()
	{
		Query=q;
	}	
	global SICS(String q)
	{ 
		Query=q;
	}

	global Database.querylocator start(Database.BatchableContext BC)
	{
		return Database.getQueryLocator(query);
	}
		
	global void execute(Database.BatchableContext BC, List<Account> scope)
	{
		List <Account> Acc2Up = new List<Account>();
		for(Account acc : scope)
		{
			IF(acc.Temp_BadCMSIC__c != NULL)
			{
			   acc.CMSIC8A__c = acc.Temp_BadCMSIC__c;
				Acc2Up.add(acc);
			}
		}
		if(Acc2Up.size() > 0 )
		{
			Update Acc2Up;
		}	
	}
}

Then execute below code form your anonymous block
// SICS obj = new SICS(); 
Id batchJobId = Database.executeBatch(new SICS(),200);

Let us know if this will help you

 
Charisse de BelenCharisse de Belen
You can use the public access modifier for Batchable Apex. The reason most documentation uses global is because it was the only option when Database.Batchable was first available.
Rafael Suarez 14Rafael Suarez 14
Hi @Amit Chaudary;

Thanks for trying to help. Unfortunately your snippet begets the same error message that mine does; "Line: 1, Column: 14
Global type must be contained inside of a global class
"...  As Charisse stated, it seems the anonymous console does not allow this.

 
Amit Chaudhary 8Amit Chaudhary 8
I just updated your Batch job like below and also tested in org
global class SICS implements Database.Batchable<sObject> 
{    
    global final String Query;
    string q = 'Select Id, CMSIC8A__c, Temp_BadCMSIC__c from Account where Temp_BadCMSIC__c != NULL ';

    global SICS()
    {
        Query=q;
    }   
    global SICS(String q)
    { 
        Query=q;
    }

    global Database.querylocator start(Database.BatchableContext BC)
    {
        return Database.getQueryLocator(query);
    }
        
    global void execute(Database.BatchableContext BC, List<Account> scope)
    {
        List <Account> Acc2Up = new List<Account>();
        for(Account acc : scope)
        {
            /*
            IF(acc.Temp_BadCMSIC__c != NULL)
            {
               acc.CMSIC8A__c = acc.Temp_BadCMSIC__c;
                Acc2Up.add(acc);
            }
            */
        }
        if(Acc2Up.size() > 0 )
        {
            Update Acc2Up;
        }   
    }
    global void finish(Database.BatchableContext BC) {
    }    
}

Then execute below code form your anonymous block
Id batchJobId = Database.executeBatch(new SICS(),200);

Let us know if this will help you