Job calls procedure not exactly same interval, which is defined in schedule - oracle

I have table with TIMESTAMP type column.
I have procedure which inserts into this table:
CREATE OR REPLACE PROCEDURE my_procedure
AS
BEGIN
INSERT INTO t2
(dt)
VALUES
(LOCALTIMESTAMP);
END;
Then create schedule:
BEGIN
dbms_scheduler.create_job(
job_name => 'my_job',
job_type => 'stored_procedure',
job_action => 'my_procedure',
start_date => '2016-10-31 17:01:01',
repeat_interval => 'FREQ=SECONDLY;INTERVAL=10',
end_date => '2016-11-30 17:01:01',
auto_drop => FALSE
);
END;
EXEC dbms_scheduler.ENABLE('my_job');
Then SELECT * FROM t2 ORDER BY dt
Results are:
2016-10-31 17:40:13
2016-10-31 17:40:21
2016-10-31 17:40:34
2016-10-31 17:40:42
2016-10-31 17:40:54
As you see, INTERVAL for schedule is 10 second, but difference between inserts (rows) are sometimes 8 second, sometimes 13 second, sometimes 12 second and so on.
Question: why is so not exactly that interval between procedure calls, which is defined in schedule?

Related

How to schedule one time executable job in Oracle?

I want to schedule a job that will execute only once; example on 01/01/2023 00:00:00. It should not repeat again. This job will call a program with a stored procedure that will update some tables.
I have written the below code by referring the answers of this question. It is not working when I set the end_date as the same date with different time. Is repeat_interval mandatory?
-- Procedure
CREATE OR REPLACE PROCEDURE P_INSURANCE_DEACTIVATION
IS
BEGIN
UPDATE SCHEME SET SCC_STATUS = 'N', US_CODE = 'D001' WHERE SC_CODE = 'N013';
UPDATE INSURANCE SET INC_STATUS = 'N', US_CODE = 'D001' WHERE IN_CODE = 'N007';
COMMIT;
END;
-- Schedule
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'SCH_INSURANCE_DEACT',
start_date => TO_DATE('22-12-2022 18:05:00','DD-MM-YYYY HH24:MI:SS'),
repeat_interval => 'FREQ=MINUTELY; INTERVAL=1; ',
end_date => TO_DATE('22-12-2022 18:07:00','DD-MM-YYYY HH24:MI:SS'),
comments => 'Only once');
END;
-- Scheduled Program
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROG_INSURANCE_DEACT',
program_action => 'P_INSURANCE_DEACTIVATION',
program_type => 'STORED_PROCEDURE');
END;
-- Scheduled Job
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'JOB_INSURANCE_DEACT',
program_name => 'PROG_INSURANCE_DEACT',
schedule_name => 'SCH_INSURANCE_DEACT');
END;
exec dbms_scheduler.enable('JOB_INSURANCE_DEACT’)
After looking at the documentation for DBMS_SCHEDULER, you can see that you can create a scheduled job without needing to define a schedule as long as you set a start time.
Personally, I wouldn't bother creating a procedure and program since the code being executed is so simple and it is just a one-time job.
The code below can be used to create a job that will run at midnight on Jan 1st 2023, but you might need to adjust the time zone for your scenario since midnight is at a different time depending which time zone you are in.
BEGIN
DBMS_SCHEDULER.create_job (job_name => 'JOB_INSURANCE_DEACT',
job_type => 'PLSQL_BLOCK',
job_action => q'[BEGIN
UPDATE SCHEME SET SCC_STATUS = 'N', US_CODE = 'D001' WHERE SC_CODE = 'N013';
UPDATE INSURANCE SET INC_STATUS = 'N', US_CODE = 'D001' WHERE IN_CODE = 'N007';
COMMIT;
END;]',
start_date => TIMESTAMP '2023-01-01 00:00:00 -05:00',
enabled => TRUE);
END;
As an additional note, you do not need to have a COMMIT at the end of your code being executed by a job. When a job completes, it will automatically commit.

Oracle DBMS Scheduler change in frequency on weekends

I have created a oracle dbms scheduler to execute a procedure daily at 05 AM, 10 AM, 03 PM and 08 PM. Below is the scheduler code
DBMS_SCHEDULER.CREATE_JOB
(
job_name => 'TEST_JOB'
,start_date => SYSDATE
,repeat_interval => 'FREQ=DAILY; BYHOUR=05,10,15,20; BYMINUTE=00 ;BYSECOND=0;'
,end_date => NULL
,job_class => 'DEFAULT_JOB_CLASS'
,job_type => 'PLSQL_BLOCK'
,enabled => TRUE
,job_action => 'BEGIN INSERT_IN_TABLE; END;'
,comments => 'TEST JOB'
);
now i have to modify the same scheduler to execute the same procedure only twice on weekends and run at same frequency on weekdays.
I don't want to create a different scheduler for the weekend executions because sometimes the procedure takes more than 5 hours to execute.
Please guide me if there is a better way to achieve this.
One option could be to use embedded calendars, so that you can create your own calendar expression.
Let me show you an example
SQL> BEGIN
dbms_scheduler.create_schedule('my_schedule_c_1', repeat_interval =>
'FREQ=DAILY; BYHOUR=05,10,15,20; BYMINUTE=00; BYSECOND=00; ');
dbms_scheduler.create_schedule('my_schedule_c_2', repeat_interval =>
'FREQ=DAILY; BYDAY=SAT,SUN; BYHOUR=05,10; BYMINUTE=00; BYSECOND=00;');
END;
/ 2 3 4 5 6 7
PL/SQL procedure successfully completed.
SQL> begin
DBMS_SCHEDULER.create_schedule ('MY_CALC', repeat_interval =>'my_schedule_c_1, my_schedule_c_2');
END;
/ 2 3 4
PL/SQL procedure successfully completed.
SQL>
Then , you only need to apply this schedule to your job
SQL> begin
2 DBMS_SCHEDULER.CREATE_JOB
(
job_name => 'TEST_JOB'
,start_date => SYSDATE
3 ,repeat_interval => 'MY_CALC'
4 ,end_date => NULL
,job_class => 'DEFAULT_JOB_CLASS'
,job_type => 'PLSQL_BLOCK'
5 6 7 8 9 10 ,enabled => TRUE
,job_action => 'BEGIN NULL; END;'
,comments => 'TEST JOB'
); 11 12 13
14 end;
15 /
PL/SQL procedure successfully completed.
SQL>
This way, my job will run using the MAIN_CALC schedule, which is a combination of the two different frequencies.
Of course, you can always create two jobs, but in 11g there is no option to create incompatibilities, which is an object in DBMS_SCHEDULER 12c onwards that prevents a job to start until the other is completed.
My advice, use a schedule calendar embedded with multiple frequencies

Run a query based on weekends in oracle

am new to ORACLE; please help
Am trying to run a query which pulls up records based on dates;
if date is monday the query should run thrice; that is for monday, sunday, saturday (previous days also) for others days (tue to thursday only for same day);
First, if you want to run the query three times you'll need to do that in something other than plain SQL: PL-SQL, Java, C#, something.
However if you'd like Saturday and Sunday's figures to be included in Monday's you'll need to do something like a CASE statement to change the Sats & Suns to Mons.
case when (trim(to_char((date), 'Day', 'NLS_DATE_LANGUAGE=ENGLISH'))
in ('Saturday', 'Sunday', 'Monday')) then 'Monday'
else trim(to_char((date), 'Day', 'NLS_DATE_LANGUAGE=ENGLISH'))
end
Am trying to run a query which pulls up records based on dates
For scheduling based on calendering, Oracle provides DBMS_SCHEDULER.
For example, the below job would execute every hour:
SQL> BEGIN
2 DBMS_SCHEDULER.DROP_JOB (JOB_NAME => 'test_full_job_definition');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 DBMS_SCHEDULER.create_job (
3 job_name => 'test_full_job_definition',
4 job_type => 'PLSQL_BLOCK',
5 job_action => 'BEGIN my_job_procedure; END;',
6 start_date => SYSTIMESTAMP,
7 repeat_interval => 'freq=hourly; byminute=0; bysecond=0;',
8 end_date => NULL,
9 enabled => TRUE,
10 comments => 'Job defined entirely by the CREATE JOB procedure.');
11 END;
12 /
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT JOB_NAME, ENABLED FROM DBA_SCHEDULER_JOBS where job_name ='TEST_FULL_JOB_DEFINITION'
2 /
JOB_NAME ENABL
---------------------------------------- -----
TEST_FULL_JOB_DEFINITION TRUE
SQL>
More examples here

Creating DBMS_SCHEDULER job for oracle

Trying to create job But can't compile it keeps me given this error. There is a question on oracle forums, it say's that i have to create program to wrap it. Is there any workaround for this?
-- Created on 30.09.2014 by ALI.ORHAN
declare
-- Local variables here
i integer;
begin
-- Test statements here
dbms_scheduler.create_job(job_name => 'blabla'
,job_type => 'STORED_PROCEDURE'
,job_action => 'dingdongprocedure;'
,start_date => '30-OCT-14 10.00.00 PM'
,end_date => '15-JULY-08'
,repeat_interval => 'FREQ=WEEKLY BYDAY=TUE,FRI BYHOUR=10,13'
,enable => 'TRUE'
,comments => 'SUPREME COMMENT');
end;
After i created job from PL/SQL Developer UI, i found out my syntax erorrs, new code is below;
i use sys.dbms_scheduler.create_job instead of dbms_scheduler.create_job. I don't know differances but it's not important alteration.
i used to_date to define start_date, as a fresh-starter i found this better practise.
Important I added job_class parameter to 'DBMS_JOB$'. DBMS_JOB is built_in job class of Oracle RDBMS. So you find all jobs with this query:
select * from ALL_SCHEDULER_JOBS WHERE JOB_CLASS='DBMS_JOB$'
Important My interval's were wrong you should put ; between all parameters like
repeat_interval => freq=weekly;byhour=10, 13
My first job code has another syntax error i use enable instead of enabled.
I set auto_drop false. I guess this parameter is used to drop job when it dones his job. I mean if you create a job that makes changes daily from today to next week. After end-time reaches, this job has dropped. Please correct me if i wrong.
sys.dbms_scheduler.create_job(job_name => 'BOMBASTICJOB'
,job_type => 'STORED_PROCEDURE'
,job_action => 'dingdongprocedure'
,start_date => to_date('30-09-2014 00:00:00'
, 'dd-mm-yyyy hh24:mi:ss')
,end_date => to_date(null)
,job_class => 'DBMS_JOB$'
,repeat_interval => 'Freq=Weekly; ByDay=Tue, Fri; ByHour=10, 13'
,enabled => true
,auto_drop => false
,comments => '');
I am on 12.1.0.1.0. You could create the job in a simple anonymous block :
SQL> BEGIN
2 DBMS_SCHEDULER.DROP_JOB (JOB_NAME => 'test_full_job_definition');
3 END;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 DBMS_SCHEDULER.create_job (
3 job_name => 'test_full_job_definition',
4 job_type => 'PLSQL_BLOCK',
5 job_action => 'BEGIN my_job_procedure; END;',
6 start_date => SYSTIMESTAMP,
7 repeat_interval => 'freq=hourly; byminute=0; bysecond=0;',
8 end_date => NULL,
9 enabled => TRUE,
10 comments => 'Job defined entirely by the CREATE JOB procedure.');
11 END;
12 /
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT JOB_NAME, ENABLED FROM DBA_SCHEDULER_JOBS where job_name ='TEST_FULL_JOB_DEFINITION'
2 /
JOB_NAME ENABL
---------------------------------------- -----
TEST_FULL_JOB_DEFINITION TRUE
SQL>
More examples here

DBMS SCHEDULER Job with input

Hi I have a stored procedure in oracle that I would like to run periodically. Firstly I got my DBMS_SCHEDULER Job to compile (see below) and I can even see the job be created and drop it though I don't see the result of the stored procedure occur in the table it is supposed to effect and the stored procedure has been tested.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'JOB_QUERY',
job_type => 'PLSQL_BLOCK', -- see oracle documentation on types --
job_action => 'BEGIN RUNREPORT(''NAME'', ''VERSION'', ''04-Jun-13'', ''11-Jun-13''); END;',
start_date => to_date('2013-08-19 16:35:00', 'YYYY-MM-DD HH24:MI:SS' ),
repeat_interval => 'FREQ=MINUTELY;BYMINUTE=10', -- every 10 minutes.
end_date => NULL,
enabled => TRUE,
comments => 'Daily Jira Query Update');
END;
I was attempting to simply make it run every ten minutes though I see no changes. Also I wanted to be able to pass SYSDATE or the current date to the procedure in the dbms_scheduler job but I cant get it to work with the apostrophes.
Thanks
You have to COMMIT your DML statements. There is no COMMIT in PL/SQL block and I guess in procedure RUNREPORT either.
You don't need an apostrophe around sysdate, it's not a string literal.
job_action => 'BEGIN RUNREPORT(''NAME'', ''VERSION'', sysdate, ''11-Jun-13''); COMMIT; END;',
BYMINUTE does not mean what you would expect. From documentation:
"This specifies the minute on which the job is to run. Valid values are 0 to 59. As an example, 45 means 45 minutes past the chosen hour". What you need is
repeat_interval => 'FREQ=MINUTELY;INTERVAL=10'
You can check next run date and more by querying user_scheduler_jobs.
If you are calling the stored procedure from DMBS Scheduled job you can try below.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
JOB_NAME => 'SCHEMA.MY_DBMS_SCHEDULED_JOB',
JOB_TYPE => 'STORED_PROCEDURE',
JOB_ACTION => 'SCHEMA.STORED_PROCEDURE_TO_BE_CALLED',
START_DATE => '01-AUG-13 12.00.00 AM',
REPEAT_INTERVAL => 'FREQ=DAILY;BYHOUR=0;BYMINUTE=10',
AUTO_DROP => FALSE,
ENABLED => TRUE,
NUMBER_OF_ARGUMENTS => 0,
COMMENTS => 'Scheduled job to perform updates.');
END;
/
To see if your scheduler log you can use below query.
SELECT * FROM all_SCHEDULER_JOB_LOG
where job_name='MY_DBMS_SCHEDULED_JOB'
order by log_id desc;

Resources