create oracle job run procedure with parameters once - oracle

I want to create oracle job in specific date and time that runs only on that date and time once
and then dropped automatically.
The job should runs a procedure with 2 parameters also .
note: l_id I used this variable to add number beside procedure name to avoid any kind of duplication.
P94_DATE: the user will choose date and time and it will be stored in that variable.
here what I found so far but when I run this , it gives me 'statement proceed' but when I check if the job created successfully or not on 'sys.all_scheduler_jobs'
it doesn't exist.
dbms_scheduler.create_job (
job_name => 'eba_sb_reminder_s'||l_id,
job_type => 'STORED_PROCEDURE',
job_action => 'BEGIN send_Schedule_reminders(1,2); END;',
start_date => :P94_DATE, -- I need to assign time also !!
enabled => true,
comments => 'check if there is new reminders needs to be send in specific date and time'
);
end;

When job_type is set to STORE_PROCEDURE you must specify the name of the procedure in job_action.
The parameter start_date is of type DATE, which has a time as well in Oracle. You just need to set :p94_date with a correct value, containing a date and a time part.
If the procedure has parameters, you need to use DBMS_SCHEDULER.set_job_argument_value to specify a parameter-value.
Edit: Sample modified
Sample:
BEGIN
-- This needs to be configured just once.
DBMS_SCHEDULER.create_program(program_name => 'test_program',
program_type => 'STORED_PROCEDURE',
program_action => 'test',
number_of_arguments => 2,
enabled => FALSE,
comments => 'Comment');
DBMS_SCHEDULER.define_program_argument(program_name => 'test_program',
argument_name => 'p1',
argument_position => 1,
argument_type => 'NUMBER',
DEFAULT_VALUE => NULL);
DBMS_SCHEDULER.define_program_argument(program_name => 'test_program',
argument_name => 'p2',
argument_position => 2,
argument_type => 'NUMBER',
DEFAULT_VALUE => NULL);
DBMS_SCHEDULER.enable(name => 'test_program');
-- Create job
DBMS_SCHEDULER.create_job(
job_name => 'test_job',
program_name => 'test_program',
start_date => :p94_date,
enabled => FALSE,
comments => 'check if there is new reminders needs to be send in specific date and time');
-- Set Procedure Parameter
DBMS_SCHEDULER.set_job_argument_value(job_name => 'test_job', argument_position => 1, argument_value => 1);
DBMS_SCHEDULER.set_job_argument_value(job_name => 'test_job', argument_position => 2, argument_value => 2);
-- Enable job
DBMS_SCHEDULER.enable(name => 'test_job');
END;

"It's not working" is not found an any error message reference, and is totally devoid of actionable information.
That said:
You specify JOB_TYPE as STORED_PROCEDURE, so JOB_ACTION should be the name of a stored procedure. Instead you give it the code for an anonymous block.
JOB_NAME include a string concatenation that seems to try to include a variable. Where does that value come from and how do you think it is being populated when you execute this CREATE_JOB?
3)START_DATE also seems to try to include a variable/parameter. Again, Where does that value come from and how do you think it is being populated when you execute this CREATE_JOB?
dbms_scheduler.create_job (
job_name => 'eba_sb_reminder_s',
job_type => 'STORED_PROCEDURE',
job_action => 'send_Schedule_reminders(1,2)',
start_date => to_date('2021-03-22 13:00:00','yyyy-mm-dd hh24:mi:ss'),
enabled => true,
comments => 'check if there is new reminders needs to be send in specific date and time'
If this fails to meet your requirement (esp those attempts to include some sort of paramter, please explain in more detail what you are trying to achieve with them.

Related

Oracle DBMS_SCHEDULER use case to run 1 job at a time but queue subsequent jobs to run FIFO

Create a resource, and limit jobs to 1
begin dbms_scheduler.create_resource(resource_name=>'SO_TEST_RESOURCE',units=>'1'); END;
While I can create a job, assign a resource, and even a priority, the subsequent jobs (assigned to the same resource and various priorities) that are queued, are run in random order not FIFO, and not in priority order. Looking for a way to force the next job queued (assigned to that same resource) to be the one that runs next.
DBMS_SCHEDULER.create_job (
job_name => 'SO_JOB1_TEST_RESOURCE',
job_type => 'PLSQL_BLOCK',
job_action => 'begin DBMS_SESSION.sleep(40); end;',
auto_drop => true,
start_date => systimestamp,
enabled => false);
DBMS_SCHEDULER.set_resource_constraint (
object_name => 'SO_JOB1_TEST_RESOURCE',
resource_name => 'SO_TEST_RESOURCE',
units => 1);
DBMS_SCHEDULER.SET_ATTRIBUTE(
NAME => 'SO_JOB1_TEST_RESOURCE',
ATTRIBUTE => 'job_priority',
VALUE =>1 );
DBMS_SCHEDULER.enable('SO_JOB1_TEST_RESOURCE');
.... adding more jobs 2, 3, 4 run in random order
Oracle DBMS_SCHEUDLER CHAINS is probably what you are looking for. You can create a chain first
BEGIN
DBMS_SCHEDULER.CREATE_CHAIN (
chain_name => 'my_chain1',
rule_set_name => NULL,
evaluation_interval => NULL,
comments => 'My first chain');
END;
/
... and then add each scheduled job into the chain as steps in the chain.
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'my_chain1',
step_name => 'my_step1',
program_name => 'my_program1');
DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'my_chain1',
step_name => 'my_step2',
program_name => 'my_chain2');
END;
/
There is a lot more that can be done with job CHAINS, like checking status, implementing restart logic etc. Oracle Documentation will be good reference.

dbms_scheduler - Passing log_id in event based job

I am trying to create an event based job using oracle dbms_scheduler as described below. Is there a way we can pass the job information that raised the event into the job that is executed based on that event.
Subscribing to the queue
BEGIN
sys.DBMS_SCHEDULER.add_event_queue_subscriber ('my_queue_agent');
END;
Create program that will be called by the first job
begin
sys.dbms_scheduler.create_program(program_name => 'PROGRAM_TEST',
program_type => 'STORED_PROCEDURE',
program_action => 'PROC_TEST_SCHEDULER',
number_of_arguments => 2,
enabled => false,
comments => '');
sys.dbms_scheduler.define_program_argument(program_name => 'PROGRAM_TEST',
argument_position => 1,
argument_name => 'P_JOB_NAME',
argument_type => 'VARCHAR2',
default_value => '');
sys.dbms_scheduler.define_metadata_argument(program_name => 'PROGRAM_TEST',
metadata_attribute => 'LOG_ID',
argument_position => 2,
argument_name => 'LOG_ID');
sys.dbms_scheduler.enable(name => 'PROGRAM_TEST');
end;
Create job that utilizes the program.
begin
sys.dbms_scheduler.create_job(job_name => 'TEST_PROGRAM_JOB',
program_name => 'PROGRAM_TEST',
start_date => to_date(null),
repeat_interval => '',
end_date => to_date(null),
job_class => 'DEFAULT_JOB_CLASS',
enabled => false,
auto_drop => false,
comments => '');
sys.dbms_scheduler.set_job_argument_value(job_name => 'TEST_PROGRAM_JOB',
argument_name => 'P_JOB_NAME',
argument_value => 'TEST_PROGRAM_JOB');
sys.dbms_scheduler.set_attribute(name => 'TEST_PROGRAM_JOB', attribute => 'raise_events', value => sys.dbms_scheduler.job_started + sys.dbms_scheduler.job_succeeded + sys.dbms_scheduler.job_failed);
end;
Create second job that would be triggered based on events of first job.
BEGIN
sys.DBMS_SCHEDULER.create_job (
job_name => 'UPDATE_STATUS_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'insert into t_log values (''UPDATE'' || tab.user_data.log_id,sysdate);',
event_condition => '(tab.user_data.event_type = ''JOB_SUCCEEDED'' OR
tab.user_data.event_type = ''JOB_FAILED'' or
tab.user_data.event_type = ''JOB_STARTED'' or
tab.user_data.event_type = ''JOB_COMPLETED'') AND tab.user_data.object_name = ''TEST_PROGRAM_JOB''',
queue_spec => 'sys.scheduler$_event_queue,my_queue_agent',
enabled => TRUE);
END;
Is there a way I can pass the current log_id of TEST_PROGRAM_JOB into UPDATE_STATUS_JOB? I want to log the status of the TEST_PROGRAM_JOB. Right now, I tried using tab.user_data.log_id but with no success.
sys.dbms_scheduler.define_metadata_argument only works with 'job_name', 'job_subname', 'job_owner', 'job_start', 'window_start', 'window_end', and 'event_message.
In your case try to use event_message. You can also replace p_job_name with job_name.

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.

job scheduling for a few hours everyday

I need to schedule a job starting from 0600 till 1800. The job should run after every two hours. For example 0800, 1000, 1200, 1400, 1600, 1800.
Here is the code I have managed to do so far:
DECLARE
l_id binary_integer;
begin
sys.dbms_job.submit(job => l_id, what => 'integration_export;', interval => 'TRUNC(SYSDATE,''hh24'')+0/24/60');
sys.dbms_output.put_line(l_id);
end;
This will, of course, run the job after every 2 hours without stopping at 1801 - 0759. How may I add this restriction?
One thing I though is to create another schedule procedure which wakes up at 1801 and changes NEXT_DATE for this job. However, I am wondering if it is a good idea.
Any suggestions?
Thanks in advance :-)
dbms_job is old. I'd recomend you use the dbms_scheduler (introduced in Oracle 10g) instead.
dbms_scheduler.create_job(job_name => 'YOUR_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'integration_export;',
start_date => systimestamp,
repeat_interval => 'freq=hourly; byhour=8,10,12,14,16,18; byminute=0; bysecond=0;',
enabled => true,
auto_drop => false,
comments => 'some comment about the job');
Instead of dmbs_job, use the advanced dbms_scheduler. Here is an example:
begin
DBMS_SCHEDULER.create_job (
job_name => 'Integration_export',
job_type => 'PLSQL_BLOCK',
job_action => 'integration_export;',
start_date => SYSTIMESTAMP,
enabled => TRUE,
repeat_interval => 'freq=daily; byhour=6,8,10,12,14,16,18; byminute=0; bysecond=0');
end;
/

What is the syntax for adding parameters to the called procedure in Oracle scheduler?

So say I have 2 procedures: MYPROC1 & MYPROC2(A_PARAM INTEGER)
this works:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'TEST_SCHEDULER',
job_type => 'STORED_PROCEDURE',
job_action => 'developer.MYPROC1', <<<<<<<<<<<<<<<
start_date => TIMESTAMP'2011-12-4 10:30:00',
repeat_interval => 'FREQ=SECONDLY;INTERVAL=30',
end_date => TIMESTAMP'2011-12-4 10:45:00',
auto_drop => FALSE,
comments => 'TEST 1');
END;
replacing line 5 with:
job_action => 'developer.MYPROC1(2)' makes it not work.
Error: ..invalid name for a database object...
So how do I call from a scheduler a parametrized procedure? Whats the syntax?
use job_type => 'PLSQL_BLOCK', job_action => 'BEGIN developer.MYPROC1(2); END;' instead.
Leave your job_action parameter as it is (without the arguments), and add the number_of_arguments option to the number if parameters your procedure expects.
You can then use DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE to set the argument values.
Examples here: Using jobs.
Firsly, create your scheduler job by using DBMS_SCHEDULER.CREATE_JOB without enabling (default is false, already), and then that should be enabled to run.
It' nice to define job_name parameter as a bind variable for consecutive job names.
job_name parameter needn't to be in upper cases, but when querying scheduler run history, call it with all letters of job_name in upper from a privileged schema :
select *
from dba_scheduler_job_log l
where l.job_name = 'TEST_SCHEDULER'
order by l.log_date desc;
Don't forget to include number_of_arguments(for this case it equals 1) parameter for your job creation command.
As Mat tells you may use DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE like in the following example ( also define argument value parameter as a bind variable with value 2 as in your case ) :
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => '&v_job_name', -- tEst_sCheDuLEr
job_type => 'STORED_PROCEDURE',
job_action => 'developer.MYPROC1',
number_of_arguments => 1,
start_date => '04-apr-2018 10:30:00 am',
repeat_interval => 'FREQ=SECONDLY;INTERVAL=3;',
end_date => '04-apr-2018 10:45:00 am',
auto_drop => false,
comments => 'TEST 1');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
job_name => '&v_job_name',
argument_position => 1,
argument_value => &vl -- 2
);
DBMS_SCHEDULER.ENABLE('&v_job_name');
END;
If you get ORA-01882 Timezone region not found error, then
to_timestamp_tz('04-APR-2018 10:30:00 EST', 'DD-MON-YYYY HH24:MI:SS TZR')
or to_date('04.04.2018 10:30:00', 'DD.MM.YYYY HH24:MI:SS')
format may be used for start_date parameter.

Resources