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

Not able to delete Completed Scheduled Jobs in Apex Code?



My requirement is to delete all the completed scheduled jobs (becoz of 10 limit in org) and then kick off a process every n minutes.


Somehow I am not getting any job in completed state although some of the jobs have run in past. All the jobs show in Waiting state.

Here is the sample code (where i am deleting all jobs which is not right ) :


List<CronTrigger> completedJobs =[Select c.State, c.EndTime, c.OwnerId, c.Id,c.TimesTriggered, c.NextFireTime,
    c.CronExpression From CronTrigger c ];


 //where c.State = 'Completed'
    //where c.EndTime < :currentTime
        System.debug('Scheduled Job Size is ::'+completedJobs.size());
        for(CronTrigger cronJob:completedJobs){
            System.debug(':: Job to Abort::'+String.valueOf(cronJob) + ' c.TimesTriggered ' + cronJob.TimesTriggered
            + ' c.NextFireTime ' +cronJob.NextFireTime);

           // to exclude current job to be deleted

           if(cronJob.Id !=triggerId ) {
                System.debug(':: Job aborted ::'+String.valueOf(cronJob) );
                System.debug(':: Cannot abort this Job ::'+String.valueOf(cronJob) );


I am stuck so as to how to identify completed jobs and then delete them.


Is it some sfdc bug that the schedule job is never shown in completed state? Can anybody let me know if I am missing something?







I am quite sure that it is a sfdc bug. I have scheduled same job 5 times and even after the jobs have finished execution, they still show me in waiting state.


This is a priority for me so in case anybody has faced this issue or has any idea on this please let me know.


Pls note - My objective is to delete the completed jobs.







I was also facing a similar situation in which the jobs I had scheduled for a particular time showed status as "WAITING" although it completed the current execution.


What I have concluded after some analysis is that although the particular scheduled job has completed it's current execution, it was scheduled again for the next execution since my Cron expression was so.

The expression was  '0 0 22 ? * WED' which meant that after the job runs once at 10.00 PM on Wednesday, it would again get scheduled for 10 PM on the next Wednesday. So the job was again going to "WAITING" state when I checked status after the 1st execution.


I guess the same might be the case in your scenario also. You would have mentioned '*' for any of the value in your Cron expression which is causing the job to be scheduled again as per that. In effect it is not getting "Completed".


When I tried with an expression like '0 41 21 9 NOV ? 2011' in which the job was scheduled for just a single run, it returned the status as "DELETED" and no "NextFireTime" in the CronTrigger object.


So if your scenario is such that you can modify your expression for a single run, you can check for the above 2 and abort the job and rescedule it again.

I hope the above helps you.





Hi Laks


Below is my code to run the scheduled job for every half n hour . I am executing it anonymously through System Log.

My question is when i  schedule it anonymously will it run every half n hour ? or do I have to go thru Schedule Apex class button.?

And if i am scheduling anonymously why dont I see the results in Apex jobs?


Kindly help

global class updateOpportunityStage implements Database.Batchable<sObject>,Schedulable{
global string query ;

global updateOpportunityStage(){

Query = 'Select Id,BigMachines__Status__c  from BigMachines__Quote__c' ;


global database.querylocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);    
    global void execute(SchedulableContext SC){
        updateOpportunityStage stg = new updateOpportunityStage();
        String cronStr = '0 0 * 30 * ?n';
        System.schedule('Process Quotes', cronStr, stg);

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

        Set<id> liOppIds = new Set<id>();
//List <Opportunity> oppList = new List<Opportunity>() ;
for(sObject s : scope){

BigMachines__Quote__c quote = (BigMachines__Quote__c)s;
// System.debug('Adil'+quote);
if(quote.BigMachines__Status__c == 'unison' && quote.BigMachines__Is_Primary__c == true)


//query all the opportunities in a single query
List<Opportunity> opp = new List<Opportunity>();
opp = [select id, StageName from Opportunity where id in :liOppIds and stagename != 'Closed Won'];
for ( Opportunity opps : opp)
opps.StageName = 'Closed Won' ; 
//update all opportunities in a single DML
if(opp.size() > 0)
update opp;
  global void finish(Database.BatchableContext BC){}  


 Thanks for the help