Good day.
A little background ...
There was an Oracle 12.2 database.
It used the DBMS_JOBS packages and used the expression
dbms_job.next_date (job, nvl (datetime, sysdate));
Recently migrated DB to Oracle 19
Please tell me how in DBMS_SCHEDULER the next start of the job appears?
Is it possible to update the date of the next launch, substituting the date in the format 'DD.MM.YYYY HH24: MI: SS' from a previously prepared table or from a function that determines when it is necessary to start a job?
In DBMS_SCHEDULER you can create even complex schedule times, see example calculate hours based on business hours in Oracle SQL
How do you run dbms_job.next_date? Perhaps instead of setting the start time of your job, just execute the job manually with DBMS_SCHEDULER.RUN_JOB(job_name, FALSE);.
Or create a Scheduler Job without start time
BEGIN
DBMS_SCHEDULER.CREATE_JOB
(
job_name => '<job_name>'
,start_date => NULL
,repeat_interval => NULL
,end_date => NULL
,job_class => 'DEFAULT_JOB_CLASS'
,job_type => 'PLSQL_BLOCK'
,job_action => '<PL/SQL procedure>'
);
DBMS_SCHEDULER.SET_ATTRIBUTE
( NAME => '<job_name>'
,attribute => 'AUTO_DROP'
,VALUE => FALSE);
END;
And then set the start time when you like to run it:
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE
( name => '<job_name>'
,attribute => 'START_DATE'
,value => TIMESTAMP '2021-11-05 12:30:00');
END;
Just another note, a DATE or TIMESTAMP does not have any format as such. The values are stored as internal byte values, what you see is the (default) output format according to current session NLS_DATE_FORMAT / NLS_TIMESTAMP_FORMAT. You should never store date/time values as string, it's a design flaw.
If you just like to know, when your jobs runs the next time, run this query:
SELECT JOB_NAME, START_DATE, END_DATE, LAST_START_DATE, NEXT_RUN_DATE
FROM ALL_SCHEDULER_JOBS
WHERE JOB_NAME = '<job_name>';
As far as I can tell, there's no next_date there. Scheduler uses (as documentation says)
rich calendaring syntax to enable you to define repeating schedules, such as "every Tuesday and Friday at 4:00 p.m." or "the second Wednesday of every month." This calendaring syntax is used in calendaring expressions in the repeat_interval argument of a number of package subprograms.
According to that, I'm not sure you can easily "convert" dates stored in your table into such a calendar.
You could, though, schedule a job that runs only once, at a time fetched from your table, and use it as scheduler's start_date parameter.
As a result, I did the following: Created, in which the time of the next job start is picked up from the tuning table.
.....................
declare
planner_time DATE :=to_date(app_plan.svc.get_setting('PLANNER_NEXT_TIME'),'DD.MM.YYYY HH24:MI:SS');
.....................
IF SYSDATE> = planner_time
THEN
dbms_scheduler.run_job (job_name => JOB_NAME || PLANNER_ID);
END IF;
.....................
And I put this procedure in a new job that runs every 2 minutes
Related
In oracle 11g, if I have a job A, is it possible to schedule it in such a way that, the job will repeatedly execute from 10am to 11am every day.
Yes it can be scheduled.
Oracle Job Queue
The Oracle job queue allows for the scheduling and execution of PL/SQL routines (jobs) at predefined times and/or repeated job execution at regular intervals. Oracle provides a built-in package DBMS_JOB to schedule the jobs. The DBMS_JOB package is actually an API into an Oracle subsystem known as the job queue. The DBMS_JOB package is created when the Oracle database is installed.
You can get details on : https://www.developer.com/db/article.php/3713896/Scheduling-Jobs-in-the-Database.htm
You can do as follows, the below will execute from 10 A.M. to 11 A.M. repeatedly every 10 minutes (change the frequency as per your requirement)
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'JOB_NAME',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN your_procedure_name; END;',
start_date => SYSDATE,
repeat_interval => 'FREQ=DAILY; BYHOUR=10,11; BYMINUTE=0,10;',
enabled => TRUE,
auto_drop => FALSE);
END;
/
"it should execute as much time as possible"
Keep in mind, the job you are executing as much as possible during the one hour time should not be overkill
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'JOB_NAME',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN your_procedure_name; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=SECONDLY;BYHOUR=10,11;',
enabled => TRUE,
auto_drop => FALSE);
END;
/
This will execute the job action at most once a second, depending on the duration of the job. One second resolution between successive job executions is a dbms_scheduler limitation. The repeat_interval in case of an ical expression is executed after the job finished, so if a duration is 10 seconds then it will execute after at most once every 10 seconds. There can only be a single instance of the same job executing at the same time.
If you need to execute an action multiple times a second then you will need to create multiple jobs with the same action and secondly interval, which then could execute at the same time.
If you still need multiple executions per second but only one instance should be running at all times (that will run within a fraction of a second), then attach the same resource to each job.
begin
dbms_scheduler.create_resource(resource_name=>'TEST_RESOURCE',
units=>'1');
DBMS_SCHEDULER.set_resource_constraint (
object_name => 'JOB1_TEST_RESOURCE',
resource_name => 'TEST_RESOURCE',
units => 1);
DBMS_SCHEDULER.set_resource_constraint (
object_name => 'JOB2_TEST_RESOURCE',
resource_name => 'TEST_RESOURCE',
units => 1);
END;
/
One last thing is that if using systimestamp as the start date the byhour values are fixed as in the current gmt offset. For example if the job was created when daylight saving time was active, it could behave as specified BYHOUR=9,10 in standard time(winter time). This depends on the timezone value of your operating system the database is running on.
To avoid this use "at time zone" as in
SYSTIMESTAMP AT TIME ZONE 'US/Pacific'.
Also one could omit the start_time provided that the scheduler default time zone is set correctly. See
dbms_scheduler.get_scheduler_attribute('default_timezone')
and
dbms_scheduler.set_scheduler_attribute('default_timezone', 'your time zone')
I am trying to create a task (delete some cache data) that will run once in two days. This will run on Oracle 11g. So far I came up with the following anonymous block:
begin
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'clear_cache',
job_type => 'PLSQL_BLOCK',
job_action => 'begin delete from MY_CACHE;commit; end;',
start_date => to_date('19/09/2016','dd/mm/rrrr')+ 19/24,
repeat_interval => 'to_date(''19/09/2016'',''dd/mm/rrrr'')+ 2 + 19/24',
enabled => TRUE);
end;
However, I am not sure about repeat_interval value..
Assuming that I will run this block today (15/09/2016), I want clear_cache to be executed on:
19/09/2016 at 7 p.m
21/09/2016 at 7 p.m.
23/09/2016 at 7 p.m.
etc
I know that if i use
start_date => sysdate,
repeat_interval => 'trunc(sysdate) + 7 + 7/24'
Then it will start execution today, will repeat every 7 days at 7 p.m., what I want,though, is to begin next Monday and repeat every 2nd day and I am not sure how to achieve that...
So, I would like to know what exactly to put into repeat_interval ...
Thanks.
It's worth using the built-in calendaring syntax rather than trying to roll your own. By stating that you want the job to run daily with an interval of 2 it will run every 2 days.
The syntax is FREQ=DAILY;INTERVAL=2, if you set the start date to 7pm then it'll start at that time in your current timezone.
The start_date parameter is a date, so you can use an actual date or timestamp here.
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'clear_cache',
job_type => 'PLSQL_BLOCK',
job_action => 'begin delete from MY_CACHE; commit; end;',
start_date => timestamp '2016-09-19 19:00:00',
repeat_interval => 'FREQ=DAILY;INTERVAL=2',
enabled => TRUE);
Hi i have to show one report and the report data should refresh on every monday.
automatically
I have checked oracle scheduler . i cant see any option for limiting the interval to monday
.
I am thinking to give start date as monday and repeat 7 days interval .
is it good way
Hi I got the answer.
YOU want to right like the code below.
There are 3 way for scheduling a job on every week day it can be every monday or another day
Here i have tried for running the job automatically on every monday 6 am
We have to set the frequency
either of the below code we can use
FREQ=DAILY; BYDAY=MON; BYHOUR=6; BYMINUTE=0; BYSECOND=0;
FREQ=WEEKLY; BYDAY=MON; BYHOUR=6; BYMINUTE=0; BYSECOND=0;
FREQ=YEARLY; BYDAY=MON; BYHOUR=6; BYMINUTE=0; BYSECOND=0;
begin
dbms_scheduler.create_job(
job_name => 'JOB_TEST',
job_type => 'PLSQL_BLOCK',
job_action => 'begin PROCEDURE_NAME; end;',
start_date => systimestamp,
end_date => null,
comments => 'job is created for running automatically on every monday',
enabled => true,
repeat_interval => 'FREQ=WEEKLY; BYDAY=MON; BYHOUR=0; BYMINUTE=0; BYSECOND=0;');
end;
In oracle We can write jobs using DBMS Scheduler or DBMS JOBS
DBMS Scheduler is the above example and its the advanced one,
IF you want to Do the same Problem Using DMBS JOBS
begin
sys.dbms_job.submit(job => :job,
what => 'procedure name;',
next_date => NEXT_DAY(TRUNC(SYSDATE),'MONDAY'),
interval => 'NEXT_DAY(TRUNC(SYSDATE),''MONDAY'')');
commit;
end;
/
I want make JOBS use DBMS_SCHEDULER in oracle 10g, where jobs refresh minutely with interval 2 minute running everyday start at 08.00 AM and end at 08.00 PM. I have tried this code,
BEGIN
SYS.DBMS_SCHEDULER.CREATE_JOB
(
job_name => 'UPDATE_REKAP_BALI'
,start_date => trunc(sysdate) + 8/24
,repeat_interval => 'freq=MINUTELY;interval=2'
,end_date => trunc(sysdate) + 20/24
,job_class => 'DEFAULT_JOB_CLASS'
,job_type => 'STORED_PROCEDURE'
,job_action => 'UPDATEREKAPBALI'
,comments => NULL
);
END
but, when i check on the next day, the jobs is not running, i guess that the jobs is never running up again on 08.00 AM at the next day.
Make sure you commit after submitting the job.
Edit This is incorrect: DBMS_SCHEDULER performs an implicit commit, unlike the previous DBMS_JOB which required an explicit commit.
You have to make auto_drop to false , because auto drop will make the job to be dropped once after it is running , so make it as false
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'TEST_J',
job_type => 'CHAIN',
job_action => 'TEST_C',
auto_drop => FALSE,
repeat_interval => 'FREQ=DAILY;BYHOUR=08,09,10,11,12,13,14,15,16,17,18,19;BYMINUTE=02,04,06,08,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,00;BYSECOND=00;',
enabled => TRUE);
END;
/
Auto Drop is enabled by default
http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sched.htm#i1000363
The answer is two links far
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sched.htm#CIHGCDBJ - Table 93-54 Window Attribute Values
'repeat_interval' line in the table point to "Calendaring Syntax" link http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sched.htm#BABFBCEF where you can find out how to set a schedule in terms of Oracle
When this code is executed in SQL Developer against Oracle 11g I get an error,
begin
dbms_scheduler.create_job(
job_name => 'comuni_34',
job_type => 'plsql_block',
job_action => 'begin com_auth_api.expire_old_passwords; end;',
start_date => to_date('2009-jan-01 01:15:00', 'yyyy-mon-dd hh24:mi:ss'),
repeat_interval => 'freq=daily',
enabled => true,
comments => 'Expire old passwords'
);
end;
This is the error,
Error starting at line 4 in command:
begin
dbms_scheduler.create_job(
job_name => 'comuni_34',
job_type => 'plsql_block',
job_action => 'begin com_auth_api.expire_old_passwords; end;',
start_date => to_date('2009-jan-01 01:15:00', 'yyyy-mon-dd hh24:mi:ss'),
repeat_interval => 'freq=daily',
enabled => true,
comments => 'Expire old passwords'
);
end;
Error report:
ORA-01870: the intervals or datetimes are not mutually comparable
ORA-06512: at "SYS.DBMS_ISCHED", line 99
ORA-06512: at "SYS.DBMS_SCHEDULER", line 268
ORA-06512: at line 2
01870. 00000 - "the intervals or datetimes are not mutually comparable"
*Cause: The intervals or datetimes are not mutually comparable.
*Action: Specify a pair of intervals or datetimes that are mutually
comparable.
A Google search did not help as it just listed loads of useless Oracle error code sites.
Maybe the source to SYS.DBMS_ISCHED/SYS.DBMS_SCHEDULER can explain this.
Update: A different job that uses '2010-apr-20 01:15:00' instead of '2009-jan-01 01:15:00' just worked maybe the problem is that dates that are too far in the past are not handled correctly.
Update: Using '2009-apr-01 01:15:00' instead of '2009-jan-01 01:15:00' just worked. However '2009-mar-01 01:15:00' did not work so there is limit one how far back a job can be started. Since I have solved my problem I cannot accept an answer that is a repeat of my solution but if someone wants to explain this further I will consider accepting that.
I don't have 11g to test it but on a 10.2.0.4 database the CREATE_JOB was successful with START_DATE as early as 01-JAN-1970. It might be a bug and you may want to check on Metalink if you have access.
I think, you have the wrong set of NLS_LANG* parameters in your session.
SQL Developer does it automaticly. Try this place at the beginnig of the script in sqlplus:
ALTER SESSION SET NLS_LANGUAGE= 'AMERICAN';
ALTER SESSION SET NLS_TERRITORY= 'AMERICA';
So after that try to run:
begin
dbms_scheduler.create_job(
job_name => 'comuni_34',
job_type => 'plsql_block',
job_action => 'begin com_auth_api.expire_old_passwords; end;',
start_date => to_date('2009-jan-01 01:15:00', 'yyyy-mon-dd hh24:mi:ss'),
repeat_interval => 'freq=daily',
enabled => true,
comments => 'Expire old passwords'
);
end;
/
Thanks! This is the only relevant info about that problem I found, Google showed no results...
I faced a similar problem with SQL Developer 18.3.0.277 and Oracle 12c database.
It worked for me several times in the past, but suddenly it was showing that ora-01870 error.
I tried
ALTER SESSION SET NLS_LANGUAGE= 'AMERICAN';
ALTER SESSION SET NLS_TERRITORY= 'AMERICA';
but it didn't help.
What helped at the end was SQL Developer restart, really. Disconnect and connect or drop job/create job was not helping. The error was shown every time when I wanted to enable the job.
I made no alter session or similar before problem occurred. I simply disabled job and when I wanted to enable back again that error was shown.
You might consider the behavior of function OVERLAPS. I don't know if Scheduler uses it, but the error message is the same:
SQL> select 1 from dual where (sysdate,sysdate+2) overlaps (sysdate+1,sysdate+5);
1
----------
1
SQL> select 1 from dual where (null,sysdate+2) overlaps (sysdate+1,sysdate+5);
1
----------
1
SQL> select 1 from dual where (sysdate+2,null) overlaps (sysdate+1,sysdate+5);
1
----------
1
SQL> select 1 from dual where (null,null) overlaps (sysdate+1,sysdate+5);
select 1 from dual where (null,null) overlaps (sysdate+1,sysdate+5)
ORA-01870: the intervals or datetimes are not mutually comparable