function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
dJadhavdJadhav 

To Many SOQL:101

Hi ,

In my application, I want to write scheduler.The code from schduler is executing for each user from organization.

For each user, I have to execute arrount 20 DML +SOQL statements.
I have more than 100 user so getting Limit exception :Too many SOQL :101


Can anyone help?

 

Thanks in advance.

 

Regards,
Dipak

kranjankranjan
Hi Dipak,

It seems you are just having the scheduler class and you are processing the data for all users in that scheduler execute method. And therefore hitting the 101 SOQL limit.

You need to create another class which implements the Batchable interface and you need instantiate this batch class and pass the query for users to the executeBatch method which will take 2 parameters i.e. the Batch class instance and query. Something like this below:

global void execute(SchedulableContext SC) {
//Fetching all Users
String query = 'Select Id from User';

//Passing SQL to Batch job
BatchClass job = new BatchClass (query);
//Calling Batch job for 1 user
ID batchprocessid = Database.executeBatch(job, 1);
}

Check the following link for an example of batch job and its structure.

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

Hope this helps.
dJadhavdJadhav

Hi ,


Thanks for the reply.


I have written my code in batch and tried to test it. I am getting exception as Too Many SOQL:201

 

My Code:

 

/This is the scheduler class 
global class GetEventDetailsScheduler implements Schedulable{ 

//Cron expression to run the scheduler for every hour. 
//Seconds Minutes Hours Day_of_month Month Day_of_week optional_year 
public static String CRON_EXP = '0 0 0-23 ? * SUN-SAT';

 //Default constructor 
 global void GetEventDetailsScheduler(){}

 //Method which invoke the Database.executeBatch() method 
global void startGetEventDetailsScheduler (){ 
String query='select Id,UserName from User where isActive=true';
 GetWebExEventDetailsBatch webExEventDetails= new GetWebExEventDetailsBatch(query); 
 Database.executeBatch(webExEventDetails, 1); 
}
// Method which invoked from VF page to start the Scheduler.
 public static void start(){ 
 System.schedule('Get Event Details', CRON_EXP, new GetEventDetailsScheduler()); 
 }
 // Method from Schedulable interface.
 global void execute(SchedulableContext ctx){ 
 startGetEventDetailsScheduler(); 
 }
}


 /**
 * This is the batch job to get the details of each event of each user. 
 * */
global  class GetWebExEventDetailsBatch implements Database.Batchable<User>,Database.AllowsCallouts, Database.Stateful{
//Variable to store the query string.
private String query;

// Parametrized constructor which takes parameter of of the type String.
global GetWebExEventDetailsBatch(String query){
		this.query =query;
	}
// Method which  returs the all active users from the oragnization.
global Iterable<User> start(Database.batchableContext BC){
		return Database.query(query);
	}
	global void execute(Database.BatchableContext BC, List<User> users){
		for(User orgUser: users){
			if(null!=orgUser){
				// Check permission for each custom object.
				Id userId=orgUser.Id;
				if(checkObjectPermission(userId)){
				  SOQL to get all the active events and created by the orgUser.
				  for each active event{
				    // 1 callout . 
					// process the callout. 
				  }
				}
			}
		}
		// 3 more DMLS
	}
global void finish(Database.BatchableContext BC){	
 /* Schedule 1 more batch for another callout. This batch has same process. */
}

//Check the permission for 3 objects so I have 3 SOQL.
public static boolean checkObjectPermission(Id userId){
ObjectPermissions obj1=[SELECT PermissionsRead,PermissionsEdit,PermissionsDelete,PermissionsCreate
			                  FROM ObjectPermissions  where (ParentId IN (SELECT PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId=:userId))
			AND (SobjectType ='ob1')];
			ObjectPermissions obj2=[SELECT PermissionsRead,PermissionsEdit,PermissionsDelete,PermissionsCreate
			                  FROM ObjectPermissions  where (ParentId IN (SELECT PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId=:userId))
			AND (SobjectType ='ob2')];
			ObjectPermissions obj3=[SELECT PermissionsRead,PermissionsEdit,PermissionsDelete,PermissionsCreate
			                  FROM ObjectPermissions  where (ParentId IN (SELECT PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId=:userId))
			AND (SobjectType ='ob3')];

// logic to chekc the permissions foor each objects

if user has permissions to all three object then return true else false.	
	
}
}

 

Can you please  tell me the better way to write Batch job? Also tell me ,  how may times i can run the Sceduler in a day?

 

 Thanks,

Dipak

 

 

stcforcestcforce

google "apex best practices" and 'governor limits".  You have to use lists, maps, sets to group soql queries. A general illustration of the concept where the requirement is finding an owner on an account trigger:

 

for(account a: Trigger.new)

{

    user u = [select u.id from user u where u.id =: a.ownerid];

}

 

results in lots of queries. It should be:

 

set<id> owners = new set<id>();

for(account a: Trigger.new) owners.add(a.ownerid);

user[] users = [select u.id from user u where u.id in: owners];

//now find the individual user for the account programmatically.

 

 

kranjankranjan
Hi Dipak,

Can you paste the complete code. As overall things looks fine in the above code. So the exception coming could really be because of the code which is shown as comments here.

dJadhavdJadhav

Hi,

 

Thanks for reply.

 

I am changing my logic to get events for user. In execute method of Batch , I have moved the logic to Scheduler. I am testing this logic.

 

 

Thanks,

Dipak