How to Create Jobs with DBMS_SCHEDULER.CREATE_JOB

Schedule PL/SQL to run nightly with one call, run it on demand to test it, check its runs, and stop or drop jobs.

The Oracle Scheduler runs PL/SQL, stored procedures, and programs on a schedule, inside the database. DBMS_SCHEDULER.CREATE_JOB defines a job in one call: what to run, when to start, and how often to repeat. RUN_JOB runs it on demand, STOP_JOB stops a running job, and DROP_JOB removes it.

Code for This Guide

The main examples are in the examples/pkg-scheduler folder of the Oracle Database 26ai code repository on GitHub, each with its output. They use NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder.

They come from Oracle Database 26ai SQL and PL/SQL Book.

Syntax

dbms_scheduler.create_job(
  job_name        => 'NAME',
  job_type        => 'PLSQL_BLOCK',        -- or STORED_PROCEDURE, EXECUTABLE, CHAIN
  job_action      => 'begin ... end;',
  start_date      => timestamp_with_time_zone,
  repeat_interval => 'calendar expression',
  enabled         => true,
  comments        => '...');

Without a REPEAT_INTERVAL the job runs once. Without a START_DATE it starts as soon as it is enabled.

The examples log to a small table:

Setup:

create table job_log (logged_at timestamp default systimestamp,
                      job_name varchar2(30), message varchar2(200));

Create a Nightly Job

Example:

begin
  dbms_scheduler.create_job(
    job_name        => 'NIGHTLY_STATUS_CLEANUP',
    job_type        => 'PLSQL_BLOCK',
    job_action      => q'[begin
                            insert into job_log (job_name, message)
                            select 'NIGHTLY_STATUS_CLEANUP',
                                   count(*) || ' flights scheduled'
                            from   flights where status = 'SCHEDULED';
                            commit;
                          end;]',
    start_date      => timestamp '2027-01-01 02:30:00 Asia/Dubai',
    repeat_interval => 'FREQ=DAILY; BYHOUR=2; BYMINUTE=30',
    enabled         => true,
    comments        => 'Counts the flights still scheduled, nightly');
end;
/
select job_name, state, next_run_date from user_scheduler_jobs;

Output:

PL/SQL procedure successfully completed.

JOB_NAME                  STATE        NEXT_RUN_DATE
_________________________ ____________ __________________________________
NIGHTLY_STATUS_CLEANUP    SCHEDULED    01-JAN-2027 02:30:00 ASIA/DUBAI

The job counts the flights still scheduled at 02:30 Dubai time every night, starting on 1 January 2027. USER_SCHEDULER_JOBS shows it SCHEDULED, with the next run date in the job's time zone.

Run It Now

Example:

begin
  dbms_scheduler.run_job('NIGHTLY_STATUS_CLEANUP', use_current_session => true);
end;
/
select job_name, message from job_log;

select job_name, status, error#, run_duration
from   user_scheduler_job_run_details
where  job_name = 'NIGHTLY_STATUS_CLEANUP'
and    log_date > systimestamp - interval '1' minute;           -- this run

Output:

PL/SQL procedure successfully completed.

JOB_NAME                  MESSAGE
_________________________ ________________________
NIGHTLY_STATUS_CLEANUP    538 flights scheduled

JOB_NAME                  STATUS          ERROR# RUN_DURATION
_________________________ ____________ _________ ______________________
NIGHTLY_STATUS_CLEANUP    SUCCEEDED            0 +00 00:00:00.000000

RUN_JOB with use_current_session TRUE runs the job immediately in your session and waits for it, which is handy for testing. The job wrote its count to JOB_LOG, and the run is recorded in USER_SCHEDULER_JOB_RUN_DETAILS as SUCCEEDED.

Stop and Drop Jobs

Example:

begin
  dbms_scheduler.create_job(job_name   => 'LONG_JOB', job_type => 'PLSQL_BLOCK',
                            job_action => 'begin dbms_session.sleep(60); end;',
                            enabled    => true, auto_drop => false);
end;
/
exec dbms_session.sleep(3)

select job_name from user_scheduler_running_jobs;

begin
  dbms_scheduler.stop_job('LONG_JOB');
  dbms_scheduler.drop_job('LONG_JOB');
  dbms_scheduler.drop_job('NO_SUCH_JOB');
end;
/
select job_name, status from user_scheduler_job_run_details
where  job_name = 'LONG_JOB' and log_date > systimestamp - interval '1' minute;

Output:

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

JOB_NAME
___________
LONG_JOB

begin
*
ERROR at line 1:
ORA-27475: unknown job "NIMBUS"."NO_SUCH_JOB"
ORA-06512: at "SYS.DBMS_ISCHED", line 302
ORA-06512: at "SYS.DBMS_SCHEDULER", line 843
ORA-06512: at line 4

JOB_NAME    STATUS
___________ __________
LONG_JOB    STOPPED

LONG_JOB starts at once and shows in USER_SCHEDULER_RUNNING_JOBS. STOP_JOB ends it, and its run is logged as STOPPED. Dropping a job that does not exist fails with ORA-27475.

Things to Know

  • Give START_DATE a time zone region, such as Asia/Dubai, so daylight saving time changes do not shift the run time.
  • Creating jobs needs the CREATE JOB privilege, which DB_DEVELOPER_ROLE includes.
  • One-time jobs are dropped after they run unless AUTO_DROP is FALSE.

When you are done, remove the job and the table:

Cleanup:

exec dbms_scheduler.drop_job('NIGHTLY_STATUS_CLEANUP')
drop table job_log purge;

Related Guides

Conclusion

DBMS_SCHEDULER.CREATE_JOB defines what to run and when in one call. Test jobs with RUN_JOB in your session, check their runs in USER_SCHEDULER_JOB_RUN_DETAILS, and stop or drop them with STOP_JOB and DROP_JOB.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted