Can not Run Completed Oracle Job again - oracle

Can not run a completed DBMS_SCHEDULER job by remove the END_DATE
Hello, everyone!
I am using oracle 12cR1,now I have a problem in DBMS_SCHEDULER jobs.
First, I created an repeated oracle DBMS_SCHEDULER jobs with END_DATE was set,
after the set END_DATE, the job completed successfully, and the enabled state of job changed to disabled automatically.
According to the running log of the job, the Operation was COMPLETED, while Additional info was REASON="End time reached"
That was expected.
Then I wanted to run the job again, I removed the END_DATE field by
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE('JOB_XXX', 'END_DATE', '');
and set the job enable by
SYS.DBMS_SCHEDULER.ENABLE(name => 'JOB_XXX');
I can see the job was enabled again and END_DATE was empty.
But The Job run again only once, and stopped, the running log of was COMPLETED, while Additional info was REASON="End time reached" again.
BEGIN
sys.dbms_scheduler.CREATE_JOB(
JOB_NAME => 'JOB_3358',
job_type => 'STORED_PROCEDURE',
JOB_ACTION => 'TEST_JOB',
START_DATE => to_date('2019-05-05 13:35:00','yyyy-mm-dd hh24:mi:ss'),
REPEAT_INTERVAL => 'FREQ= SECONDLY;INTERVAL=30',
END_DATE => to_date('2019-05-05 13:38:00','yyyy-mm-dd hh24:mi:ss'),
auto_drop => FALSE,
COMMENTS => NULL);
END;
/
begin
sys.dbms_scheduler.enable(name => 'JOB_3358');
end;
/
What I expected was that the job will run according to REPEAT_INTERVAL again,
and as end_date was empty, it should never stop.
Is there any mistake in removing END_DATE, or is this the oracle's bug?
Thanks in advance, and best Regards!

tricky one. I reproduced your problem. Then, I tried to change start_date to systimestamp when removing end_date, which again did not work. But, then I changed start_date to systimestamp plus a bit when removing end_date, and then it worked. Working example below. It seems some info about the job is cached/stored somewhere and we can remove this info by setting start_date slightly into the future so that scheduling-logic is triggered when enabling the job (my wild theory on what happens). Working example for removing end_date of completed job:
BEGIN
sys.dbms_scheduler.CREATE_JOB(
JOB_NAME => 'MYUSER.JOB_3358',
job_type => 'PLSQL_BLOCK',
JOB_ACTION => 'begin null; end;',
START_DATE => systimestamp,
REPEAT_INTERVAL => 'FREQ= SECONDLY;INTERVAL=30',
END_DATE => systimestamp + interval '2' minute,
auto_drop => FALSE,
COMMENTS => NULL);
END;
/
begin
sys.dbms_scheduler.enable(name => 'MYUSER.JOB_3358');
end;
/
-- wait until job shows as completed
exec DBMS_SCHEDULER.set_attribute_null (name=>'MYUSER.JOB_3358', attribute=>'end_date');
begin
dbms_scheduler.set_attribute (
name => 'MYUSER.JOB_3358',
attribute => 'start_date',
value => systimestamp + interval '1' minute);
end;
/
begin
sys.dbms_scheduler.enable(name => 'MYUSER.JOB_3358');
end;
/
-- job will continue to run every 30 seconds indefinitely
--cleanup
exec sys.dbms_scheduler.drop_JOB( JOB_NAME => 'MYUSER.JOB_3358');
Edit: the above does NOT reliably work. It works sometimes, but not always. The only (silly!!!) approach which reliably worked so far in my tests is:
exec DBMS_SCHEDULER.set_attribute_null (name=>'MYUSER.JOB_3358', attribute=>'end_date');
-- This line raises "ORA-27469: NEXT_RUN_DATE is not a valid job attribute" but is necessary.
exec DBMS_SCHEDULER.set_attribute_null (name=>'MYUSER.JOB_3358', attribute=>'next_run_date');
exec dbms_scheduler.enable(name => 'MYUSER.JOB_3358');

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 scheduler job not running (after enabling it)

I created a scheduler job in the following way:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'update_sales_1',
job_type => 'STORED_PROCEDURE',
job_action => 'test_job',
start_date => systimestamp,
repeat_interval => 'FREQ=SECONDLY;INTERVAL=10',
end_date => '20-NOV-2021 07.00.00 PM Australia/Sydney',
auto_drop => FALSE,
comments => 'My new job');
END;
/
The stored procedure test_job inserts record into a table.
After creating the JOB, I enabled it and waited for 20 seconds and checked the table.
I do not see the records inserted.
You should add a parameter enabled => TRUE, default is FALSE.
If you want to enable the job after creating it you can also use:
DBMS_SCHEDULER.ENABLE(name => 'update_sales_1');
If your job did run, and you don't see anything that has happened you might can look at the job run details if something went wrong:
SELECT * FROM dba_scheduler_job_run_details WHERE job_name = UPPER('update_sales_1') ORDER BY actual_start_date;

how to configure oracle job to run at every minute of 00 second

I want to create a job in oracle which runs for every minute at 00 second like 01:00 (MI:SS), 02:00 and 03:00 ...
I have created a job like as shown below
begin
sys.dbms_job.submit(job => :job,
what => 'RECONUAT.USP_LOCK_APP_AFTER_EODTIME;',
next_date => to_date('10-05-2019 17:17:32', 'dd-mm-yyyy hh24:mi:ss'),
interval => 'SYSDATE+1/1440');
commit;
end;
/
It is also running for every minute but seconds are varying like 01:00, 02:16, 03:32 ...
My requirement is to run job for every minute of 00 second.
Please suggest.
sys.dbms_job.submit is deprecated, prefer using sys.dbms_scheduler.create_job as
declare
v_job_name varchar2(32) := 'JB_LOCK_APP_AFTER_EODTIME';
begin
sys.dbms_scheduler.create_job(
job_name => v_job_name,
job_type => 'STORED_PROCEDURE',
job_action => 'RECONUAT.USP_LOCK_APP_AFTER_EODTIME',
start_date => to_date('10-05-2019 15:00:00', 'dd-mm-yyyy hh24:mi:ss'),
repeat_interval => 'FREQ=MINUTELY;INTERVAL=1;BYSECOND=0;',
auto_drop => false,
comments => 'Populates our table every minute');
dbms_scheduler.enable(v_job_name);
end;
a starting time might be chosen before the current time. Adding BYSECOND=0 to repeat_interval parameter might do the trick about exact minute.

Oracle Job Scheduler doesn't repeat the job_action

I want to repeate a Job every 5 minutes. I have a test table that I fill with random dates. If there are dates older then SYSDATE-5, than I want to delete them. The following code works only the first time I start the scheduler and it never repeats the job_action agaian:
BEGIN
SYS.DBMS_SCHEDULER.CREATE_JOB (
job_name => '"AUTHMGR"."Test2"',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DELETE FROM TEST WHERE TESTDATE < SYSDATE-5;END;',
number_of_arguments => 0,
start_date => SYSDATE,
repeat_interval => 'FREQ=MINUTELY;INTERVAL=5',
end_date => NULL,
job_class => '"SYS"."DEFAULT_JOB_CLASS"',
enabled => TRUE,
auto_drop => FALSE,
comments => 'Test');
END;
/
Do I use the repeat_interval with wrong FREQ and wrong INTERVAL?
I use the Scheduler in Oracle SQL Developer.
The problem was with the INSERT statements. There was no COMMIT after INSERT.

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