Concurrent request scheduling explained

It’s quite an interesting way that’s used to implement concurrent request schedules in Oracle Applications. In this post I’ll describe how “Periodic” and “On Specific Day” type of schedules are stored in the Database and if you will be patient enough to read all the story, I’ll give you a query that can be used to report all the request schedules in the environment.

I’ll pay attention to the repeating schedules only as requests submitted for one-time execution are not too interesting, basically, they use the fnd_concurrent_requests.requested_start_date field to store the time the request has to be executed. This field is used in repeating schedules to specify the time of next execution.

There are just 2 normal types of repeating schedules.

Defining a "periodic" schedule

Defining a 'periodic' schedule

Periodic – the request is submitted for execution in pre-defined intervals of specified number of months, weeks, days, hours or minutes.


Definig a 'on Specific Days' schedule

On Specific Days – user can choose exact dates of month or days of week when the request will be executed. There’s an option to schedule requests for the last day of months too.

There’s also a 3rd option – Advanced – this is a special option that implements possibility to run requests based on schedules, that depend on different financial calendars and financial periods. This kind of scheduling is rarely used as it’s available in few Applications products only, e.g. GL. These schedules are managed by Scheduler/Prereleaser Concurrent Manager.

There are 2 tables invoved in storing the information about schedules: fnd_concurrent_requests that stores all basic information about concurrent requests including the next time the request is scheduled for, and fnd_conc_release_classes that stores information about the schedules. Both tables can be joined by release_class_id.

The fields we are interested in are:
– contains value ‘P’ for “Periodic” schedules, “S” – for “on Specific Days” schedules and “X” – for advanced schedules.
fnd_conc_release_classes.DATE1 –
start date of the schedule (“Start at” field in the form)
fnd_conc_release_classes.DATE2 – end date of the schedule (“End at” field in the form)this information is doubled in fnd_concurrent_requests.resubmit_end_date.

fnd_conc_release_classes.CLASS_INFO – this is the most interesting field as it contains all the information needed for rescheduling. The format of the field depends on the type of schedule.

“PERIODIC” schedule

In case of Periodic schedule fnd_conc_release_classes.CLASS_INFO field contains values like “2:D:S” or X:Y:Z where:

  • X – number of months/weeks/days/hours/minutes the request has to be rescheduled from prior run.
  • Y – contains a single letter representing units
    • “M” – months;
    • “D” – days;
    • “H” – hours;
    • “N” – minutes;
    • (there is no representation of “weeks” option. If you specify interval in weeks, it’s automatically calculated and stored in “days”).
  • Z – contains a single letter to represent if the rescheduling has to be done from start or from completion of the prior run
    • S – from the start of the prior run;
    • C – from the completion of the prior run.

Some samples:

  • 30:N:S – Repeat every 30 minutes from the start of the prior run
  • 5:N:C – Repeat every 5 minutes from the completion of the prior run
  • 12:H:S – Repeat every 12 hours from the start of the prior run

It’s interesting that information about intervals of periodic schedules is duplicated in fnd_concurrent_requests table fields RESUBMIT_INTERVAL, RESUBMIT_INTERVAL_TYPE_CODE and RESUBMIT_INTERVAL_UNIT_CODE. I haven’t yet found why’s that so.

“ON SPECIFIC DAY” schedule

In case of on Specific Day schedule fnd_conc_release_classes.CLASS_INFO field contains values like “000010000000000000000000000000010000000” – a 39 character value consisting of 0 and 1. The idea is that the placement of 1-s represent the options selected through form:

  • 1-s at places 1 to 31 – represent dates, when request has to be run, eg, if the 10th character is “1” – the request is scheduled to run on 10th day of each month;
  • character “1” at the 32nd position – specifies that the request has to be run at the last day of each month;
  • 1-s at places 33 to 39 – specifies days of week (Sunday – Saturday)the request has to be run. if the 33rd character is “1” – the request is scheduled to run each Sunday, if 34th – on Monday and so on.

Some samples:

  • 000000000000000000000000000000000000001 – Days of week: Sa
  • 111111111000000000000000000000000111110 – Dates: 1 2 3 4 5 6 7 8 9. Days of week: Mo Tu We Th Fr
  • 000000000000000000000000000000010000000 – Last day of month

Reporting all schedules

Using the information given above I wrote a “small” query to provide a report like this:

Reporting all schedules

Reporting all schedules

The query was tested in Oracle Applications versions 11.5.9,, 12.0.1 and 12.0.4 so there’s a good chance it will work on others as well. The performance of the query was OK.  but I have to say – test/analyze it before running in productio.

select r.request_id,
       p.user_concurrent_program_name || case
         when p.user_concurrent_program_name = 'Report Set' then
          (select ' - ' || s.user_request_set_name
             from fnd_request_sets_tl s
            where s.application_id = r.argument1
              and s.request_set_id = r.argument2
              and language = 'US')
         when p.user_concurrent_program_name = 'Check Periodic Alert' then
          (select ' - ' || a.alert_name
             from alr_alerts a
            where a.application_id = r.argument1
              and a.alert_id = r.argument2
              and language = 'US')
       end concurrent_program_name,
         when p.user_concurrent_program_name != 'Report Set' and
              p.user_concurrent_program_name != 'Check Periodic Alert' then
       end argument_text,
       r.requested_start_date next_run,
       r.hold_flag on_hold,
              'On Specific Days',
              c.class_type) schedule_type,
         when c.class_type = 'P' then
          'Repeat every ' ||
          substr(c.class_info, 1, instr(c.class_info, ':') - 1) ||
          decode(substr(c.class_info, instr(c.class_info, ':', 1, 1) + 1, 1),
                 ' minutes',
                 ' months',
                 ' hours',
                 ' days') ||
          decode(substr(c.class_info, instr(c.class_info, ':', 1, 2) + 1, 1),
                 ' from the start of the prior run',
                 ' from the completion of the prior run')
         when c.class_type = 'S' then
          nvl2(dates.dates, 'Dates: ' || dates.dates || '. ', null) ||
          decode(substr(c.class_info, 32, 1), '1', 'Last day of month ') ||
          decode(sign(to_number(substr(c.class_info, 33))),
                 'Days of week: ' ||
                 decode(substr(c.class_info, 33, 1), '1', 'Su ') ||
                 decode(substr(c.class_info, 34, 1), '1', 'Mo ') ||
                 decode(substr(c.class_info, 35, 1), '1', 'Tu ') ||
                 decode(substr(c.class_info, 36, 1), '1', 'We ') ||
                 decode(substr(c.class_info, 37, 1), '1', 'Th ') ||
                 decode(substr(c.class_info, 38, 1), '1', 'Fr ') ||
                 decode(substr(c.class_info, 39, 1), '1', 'Sa '))
       end schedule,
       c.date1 start_date,
       c.date2 end_date,
  from fnd_concurrent_requests r,
       fnd_conc_release_classes c,
       fnd_concurrent_programs_tl p,
       (SELECT release_class_id,
               substr(max(SYS_CONNECT_BY_PATH(s, ' ')), 2) dates
          FROM (select release_class_id,
                       rank() over(partition by release_class_id order by s) a,
                  from (select c.class_info,
                               decode(substr(c.class_info, l, 1),
                                      to_char(l)) s
                          from (select level l from dual connect by level <= 31),
                               fnd_conc_release_classes c
                         where c.class_type = 'S')
                 where s is not null)
                    (a || release_class_id) = (a - 1) || release_class_id
         START WITH a = 1
         group by release_class_id) dates
 where r.phase_code = 'P'
   and c.application_id = r.release_class_app_id
   and c.release_class_id = r.release_class_id
   and nvl(c.date2, sysdate + 1) > sysdate
   and c.class_type is not null
   and p.concurrent_program_id = r.concurrent_program_id
   and p.application_id = r.program_application_id
   and p.language = 'US'
   and dates.release_class_id(+) = r.release_class_id
 order by on_hold, next_run;

I know there are some interesting lines in this query that might need some explanation, but as that is not directly connected to the topic of this post I’ll provide explanation in comments if you will ask for it.

Post a comment or leave a trackback: Trackback URL.


  • Mario Mendes  On December 16, 2008 at 23:36

    This is real cool information. Thanks for sharing. Been using package FND_REQUEST and there is no mention on how to schedule on specific days.
    Take care,

  • Bobby  On March 28, 2009 at 14:57

    Good one !!!

  • kumar  On May 11, 2009 at 08:43

    HI Maris,

    Nice post ,Please keep up the good work

  • Kevin  On October 29, 2009 at 22:06

    Maris, you made my day with this one! Been working apps for 10 years, and always wondered about the storing of the scheduling, but was too lazy or preoccupied to chase it down. Thanks for the contribution of your efforts and knowledge.

    PS, Wherever you have an “end case”, just replace with end xxx for a more detailed column name. The word case after the end keyword is being used as an alias and not part of the syntax.

    • Maris Elsins  On October 30, 2009 at 18:56

      Hi Kevin,
      I’m really glad it was useful.
      I’ve adjusted the SQL statement with proper end-cases, it was a good hint from you. Thanks a lot, I had missed it somehow.

      • Kevin  On November 7, 2009 at 02:20

        Minor detail needed. At the bottom of the query, where you have:
        AND p.concurrent_program_id = r.concurrent_program_id

        need to also add this:
        AND p.application_id = r.program_application_id

        because 2 conc progs can have same conc_prog_id, and the application_id is the differentiator.

        If you look at the indexes for fnd_concurrent_programs you will see this.

      • Maris Elsins  On November 7, 2009 at 04:13

        You’re right, I usually don’t add those application_ids because I’ve never seen any of my queries returning wrong results.

        But I just checked this query on
        select concurrent_program_id
        from fnd_concurrent_programs
        group by concurrent_program_id
        having count(*) > 1;

        It returned 44 concurrent_program_ids that are used more then once.
        So I’m fixing the SQL in the post according to your recommendation. Thanks!

  • vinayak  On November 18, 2009 at 01:17

    This is one of the best written articles i have read lately – thorough and well structured. Stumbled upon this while searching the web, and got all information (and more) i needed in this one page. Keep up the good work.


  • Amit  On May 14, 2010 at 08:43

    Hi Maris,

    It amazing.I was searching for this inforamtion and exactly got the same.

    thank you so much for this nice article.


  • kalpana  On September 24, 2011 at 00:55

    Hi Maris ,
    Its great, but i need more detail about scheduled program, i mean if suppose they selected dates like every 4,5,8,21 of month ,how to do with the same query /

    • Maris Elsins  On September 28, 2011 at 00:27


      Sorry I didn’t understand your question. How to do what with the same query?


  • kalpana  On September 28, 2011 at 02:10

    i need the result from dates
    for Specific
    Thanks in advance

  • kalpana  On September 28, 2011 at 20:20

    i got it .thanks

  • anandmandilwar  On July 17, 2012 at 20:47

    This post was an extremely useful post I have ever seen describing the Oracle concurrent jobs scheduling. Thanks again for the post. I slightly modified your script to include ‘USER’ information and ‘exclude’ the ‘on Hold’ schedule for my environment.


  • Pat Higgins  On January 17, 2013 at 23:11

    Provides the exact background that I needed. Great writeup


  • Rev  On April 4, 2013 at 17:59

    hi Maris,

    Can you please let me know whether we can get detail of delivery opts (mail address ,fax etc ) for a concurrent program which is scheduled.

    • Maris Elsins  On April 28, 2013 at 13:42


      All the details are in the database, so it’s possible to add them too.
      I haven’ t found time to do it yet, but if you need, you should be able to trace the view request form and find the query used to extract that information from the DB.

  • musta  On April 28, 2013 at 13:13

    thank you for this great job, i want to ask you a question it is very intresting.
    why do we find a duplicate sheduled requests even if we have submit only one?

    • Maris Elsins  On April 28, 2013 at 13:36

      I’ve never seen that kind of behavior. That doesn’t sound correct.
      If I schedule one request, I get only one scheduled request.

  • musta  On April 28, 2013 at 15:42

    Hi maris,
    it happens with me it’s the Workflow Background Process i have a duplicate request with the same parameters and they are submited at the same time by the same user.
    this is why i am asking for.

  • twitter followers  On May 3, 2013 at 09:46

    Keep on writing, great job! Clients may twitter followers by way of a multitude of inexpensive services.

    twitter user profile, twitter followers, attract
    more Enthusiasts with Twitter

  • Tilak  On February 13, 2014 at 16:06

    This is an excellent stuff. Thanks a lot for this.

  • Rajesh Dayal  On April 9, 2014 at 22:38

    Great Job Maris.
    I needed to update the schedule into my non-prod after clone and this article helped a lot. while trying, i figured out that you can update just FND_CONCURRENT_REQUESTS.RESUBMIT_INTERVAL and the schedule will be changed. But when you view it from front end it still shows the old schedule. So we need to change fnd_conc_release_classes.class_info as well to keep it consistent.
    Hope this helps other folks trying to achieve similar tasks i.e. increasing the resubmit interval in non-prod instances after cloning.
    I can be reached for further help on
    Rajesh Dayal.

  • shashi  On June 4, 2014 at 21:57

    We have a bunch of requests with saved (named) schedules and many more with ad hoc schedules. In order to change schedules in a uniform manner we need to create schedules upfront and assign jobs. I am trying to write a query to identify those with predefined schedules and those without. Unfortunately OWNER_SCH_ID is null, is there any other way to identify?

  • Saiprasad Khisti  On November 16, 2014 at 16:04

    I have one concurrent program scheduled with Advanced option set . I want to cancel this schedule and make a new schedule , but I am not getting the pending request so that I cancel the request. How to cancel the scheduled request ?

  • RK  On January 18, 2015 at 07:36

    Very good one. Thanks. I have 1 question, In case there are 10OU and 10 schedules for each OU for every 10 mins interval. So when i am querying, if 1 or 2 requests are in Running status (phase_code not ‘P’ and it should be ‘R’), will this script fetch that running schedule as well?

  • Karthik  On July 19, 2015 at 20:52

    Hi… I want to schedule a request set with below.

    Morning Noon Evening Night
    Sunday 6AM – 11AM 1PM – 4PM
    Monday 6AM – 11AM 1PM – 4PM 6PM -7PM 10PM – 4AM
    Tuesday 6AM – 11AM 1PM – 4PM 6PM -7PM 10PM – 4AM
    Wednesday 6AM – 11AM 1PM – 4PM 6PM -7PM 10PM – 4AM
    Thursday 6AM – 11AM 1PM – 4PM 6PM -7PM 10PM – 4AM
    Friday 6AM – 11AM 1PM – 4PM 6PM -7PM 10PM – 4AM
    Saturday 6AM – 11AM 1PM – 2PM

    Can anyone please suggest how to do.

  • Laura  On November 25, 2015 at 16:54

    Hello Maris,

    Could you help me identify where in the db is the NOTIFY column option for people when the request is completed from the scheduled request ? They say say it is in the column NOTIFY_ON_PP_ERROR, but it is not..

    select NOTIFY_ON_PP_ERROR, request_id

    I looked for it for a loong time


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

%d bloggers like this: