I have a specific scheduler job in Oracle that needs to be run every second.
I tried to create this (using a procedure):
begin
sys.dbms_scheduler.create_job(job_name => 'WBC6_PUBLIC.TESTE',
job_type => 'STORED_PROCEDURE',
job_action => 'proc_insert_data',
start_date => to_date('19-02-2020 09:00:00', 'dd-mm-yyyy hh24:mi:ss'),
repeat_interval => 'Freq=Secondly;Interval=1',
end_date => to_date(null),
job_class => 'DEFAULT_JOB_CLASS',
enabled => true,
auto_drop => false,
comments => '');
end;
/
And this (using PLSQL_BLOCK):
begin
sys.dbms_scheduler.create_job(job_name => 'WBC6_PUBLIC.TESTE',
job_type => 'PLSQL_BLOCK',
job_action => 'insert into my_table (date) values (sysdate);',
start_date => to_date('19-02-2020 09:00:00', 'dd-mm-yyyy hh24:mi:ss'),
repeat_interval => 'Freq=Secondly;Interval=1',
end_date => to_date(null),
job_class => 'DEFAULT_JOB_CLASS',
enabled => true,
auto_drop => false,
comments => '');
end;
/
But the result is the same, the job runs every ~ 4 seconds.
Is there a parameter or something I can do to run every second?
I've tried something like this before and if the procedure takes or could take more than the interval, then it is impossible. Al alternative is to run the code in a continuous loop with some kind of stop mechanism inbuilt (e.g. check a stop_table.stop_column for a "stop" condition). For example:
BEGIN
LOOP
proc_insert_data; /* run your insert */
sys.DBMS_SESSION.sleep(1); /* Pause for 1 second. */
stop_condition := stop_condition + 1;
EXIT WHEN stop_condition = 900; /* exit after 15 min OR some other mechanism of your choice */
END LOOP;
END;
/
Related
I have created an oracle job using dbms scheduler.But the status gets failed in the execution. It gives the following error. 'ORA-27367: program "Schema.PROG_SIXMONTHPRIORITY" associated with this job is disabled' But I do not have disabled the job. 'program_action => 'SIXMONTHPRIORITY'' is a procedure that I have created in the schema. When I execute that procedure separately, it gets executed.
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROG_SIXMONTHPRIORITY',
program_action => 'SIXMONTHPRIORITY',
program_type => 'STORED_PROCEDURE');
END;
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'P_SCHEDULE_3',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ= MINUTELY; INTERVAL=30; BYMONTHDAY=19; BYHOUR=13',
end_date => SYSTIMESTAMP + INTERVAL '1' day,
comments => 'Every 30 minutes');
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'CAL_SIX_MON_PRIORITY_3',
program_name => 'PROG_SIXMONTHPRIORITY',
schedule_name => 'P_SCHEDULE_3');
END;
Can anyone identify the reason for this error?
The Scheduler objects that you created can also be separately enabled or disabled. Make sure to specify "enabled => true" when creating scheduler objects:
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROG_SIXMONTHPRIORITY',
program_action => 'SIXMONTHPRIORITY',
program_type => 'STORED_PROCEDURE',
enabled => true);
END;
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'P_SCHEDULE_3',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ= MINUTELY; INTERVAL=30; BYMONTHDAY=19; BYHOUR=13',
end_date => SYSTIMESTAMP + INTERVAL '1' day,
comments => 'Every 30 minutes');
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'CAL_SIX_MON_PRIORITY_3',
program_name => 'PROG_SIXMONTHPRIORITY',
schedule_name => 'P_SCHEDULE_3',
enabled => true);
END;
For existing objects, you can set the attributes directly:
BEGIN
DBMS_SCHEDULER.ENABLE ('PROG_SIXMONTHPRIORITY');
DBMS_SCHEDULER.ENABLE ('CAL_SIX_MON_PRIORITY_3');
END;
/
I have an API package written. It has the GET_INFO procedure. I want this procedure to be performed in the background every 20 minutes. I understand what I should do with dbms_scheduler. But in general I do not understand where to register them . I will be grateful for the example or for your help with this)
I wrote such a code but I don't know where to use it:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name = 'My_Job',
job_type = 'STORED_PROCEDURE',
job_action = 'INSERT INTO TEST2(UPDATEDAT)
VALUES (sysdate);
END;',
start_date = 'systimestamp',
repeat_interval = 'FREQ=SECONDLY;INTERVAL=5',
end_date = null,
auto_drop = FALSE,
comments = 'My new job');
END;
Here is my code and I don't know where to store it.
As the job type implies, you need a procedure to be created such as
create or replace procedure Ins_Test2 is
begin
insert into Test2(updatedat) values(sysdate);
commit;
end;
and then create the scheduler through
begin
dbms_scheduler.create_job (
job_name => 'My_Job',
job_type => 'STORED_PROCEDURE',
job_action => 'Ins_Test2',
start_date => systimestamp,
repeat_interval => 'freq=minutely; interval = 20; byday=MON,TUE,WED,THU,FRI;',
enabled => true,
comments => 'My new job'
);
end;
where I added
byday=MON,TUE,WED,THU,FRI; as an extra direction if you want to run
the scheduler within the working days(you can omit that part if you'd
like).
systimestamp(get rid of quotes) for start_date might be
replaced with an upcoming time info such as start_date => '13-FEB-20 2.00.00PM Asia/Istanbul'
in my case.
And follow by listing the created schedulers by
select job_name, next_run_date
from dba_scheduler_jobs j;
And currently running ones by
select *
from user_scheduler_job_log l
order by l.log_date desc;
And drop the scheduler by
begin
dbms_scheduler.drop_job( job_name => 'My_Job' );
end;
I have to create a job periodically.
But firstly I have create a simply job to learn how to create jobs in oracle, because is the first time I use a job.
It runs at systimestamp, but the job doesn't execute.
create or replace procedure job_test
is
begin
update table_a set value_user = 'JOB_EXECUTED' where id = 1;
commit;
end;
/
Then the scheduler job
begin
dbms_scheduler.create_job(
job_name => 'test_job_A',
job_type => 'stored_procedure',
job_action => 'job_test',
start_date = SYSTIMESTAMP,
enabled => true
);
end;
/
Then I consult the column value_user and it hasn't been updated.
select * from table_A where id = 1;
Can anyone explain me what I am missing.
create table user_count (
number_of_users NUMBER(4),
time_of_day TIMESTAMP
);
CREATE OR REPLACE PROCEDURE insert_user_count AS
v_user_count NUMBER(4);
BEGIN
SELECT count(*)
INTO v_user_count
FROM v$session
WHERE username IS NOT NULL;
INSERT INTO user_count
VALUES (v_user_count, systimestamp);
commit;
END insert_user_count;
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROG_INSERT_USER_COUNT',
program_action => 'INSERT_USER_COUNT',
program_type => 'STORED_PROCEDURE');
END;
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'my_weekend_5min_schedule',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=5; BYDAY=SAT,SUN',
end_date => SYSTIMESTAMP + INTERVAL '30' day,
comments => 'Every 5 minutes');
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'my_user_count_job',
program_name => 'prog_insert_user_count',
schedule_name => 'my_weekend_5min_schedule');
END;
exec dbms_scheduler.enable('my_user_count_job’)
select * from user_count;
select job_name, status, run_duration, cpu_used
from USER_SCHEDULER_JOB_RUN_DETAILS
where job_name = ‘MY_USER_COUNT_JOB’;
Indeed your case should work but once(provided there already exists a row with id value equals to 1). Suppose you have an insert statement rather than an update, but doesn't repeat to populate the table with new incremented ID values.
For this, important point is to add repeat_interval argument such as below :
begin
dbms_scheduler.create_job(
job_name => 'test_job_A',
job_type => 'stored_procedure',
job_action => 'job_test',
start_date => SYSTIMESTAMP,
enabled => true,
repeat_interval => 'FREQ=MINUTELY;INTERVAL=5',
auto_drop => false,
comments => 'Inserts new records'
);
end;
/
which inserts new records for each five minutes.
I have Tow table with Identical Columns Given Below:
Table-1 PAYROLLFILE:
Table-2 TEMP_PAYROLLFILE:
I have written a PL SQL Function, which inserts a duplicate row from Table PAYROLLFILE to TEMP_PAYROLLFILE and remove the original row from Table PAYROLLFILE.So in short, Table TEMP_PAYROLLFILE is keeping a backup for deleted data from Table PAYROLLFILE.
Here is the PL SQL Function Code:
FUNCTION Remove_transaction_by_id(employee_id NUMBER)
RETURN CLOB
AS
cnt INT;
BEGIN
INSERT INTO temp_payrollfile
SELECT *
FROM payrollfile
WHERE empid = employee_id;
DELETE FROM payrollfile
WHERE empid = employee_id;
SELECT Count(*)
INTO cnt
FROM payrollfile;
COMMIT;
RETURN '<result><status>success</status> <row>'
||cnt
|| '</row></result>';
EXCEPTION
WHEN OTHERS THEN
RETURN '<result><status>Error</status></result>';
END remove_transaction_by_id;
However, I want to do more than that, I want to Delete Backup rows Automatically from Table TEMP_PAYROLLFILE after a specific time period is over fort that specific row.Do i need triggers.I am new on that and never done this type of work before.If anyone know this kind of technique, then i would really appreciate your help.please let me know if further details required.Thanks
Updates:
I have write this job to cleanup old rows: will it work?
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'oe.REMOVE_TEMP_PAYROLLFILE_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_STATS.GATHER_TABLE_STATS('oe',
'TEMP_PAYROLLFILE');
delete from TEMP_PAYROLLFILE where RECORDDATE < sysdate-1;
END;',
start_date => '20-JAN-16 1.00.00AM US/Pacific',
repeat_interval => 'FREQ=DAILY',
end_date => '25-JAN-16 1.00.00AM US/Pacific',
enabled => TRUE,
comments => 'Gather table statistics');
END;
What you need here is a periodic cleanup job. Using DBMS_SCHEDULER you can configure a job that does this repeatedly:
delete from TEMP_PAYROLLFILE where recorddate < sysdate-60;
to delete records that are more than 60 days old.
These are some examples on how to create a scheduled job. As you see below, the job_action sections accepts a Pl/SQL script, in which you can place your cleanup logic.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'oe.my_job1',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_STATS.GATHER_TABLE_STATS(''oe'',
''sales''); END;',
start_date => '15-JUL-08 1.00.00AM US/Pacific',
repeat_interval => 'FREQ=DAILY',
end_date => '15-SEP-08 1.00.00AM US/Pacific',
enabled => TRUE,
comments => 'Gather table statistics');
END;
/
Create a stored procedure to perform the deletion:
CREATE PROCEDURE remove_Temp_Transacts_by_ID(
in_employee_id IN NUMBER,
in_datetime IN TIMESTAMP
)
AS
BEGIN
DELETE FROM temp_payrollfile
WHERE empid = in_employee_id
AND datetime <= in_datetime;
END;
/
Then in your function include a call to schedule a job to run the procedure at a later time:
DBMS_SCHEDULER.CREATE_JOB(
JOB_NAME => 'Remove_TTbID__JOB',
JOB_TYPE => 'STORED_PROCEDURE',
JOB_ACTION => 'remove_Temp_Transacts_by_ID'
START_DATE => ( SYSTIMESTAMP + INTERVAL '2' HOURS ),
ENABLED => FALSE,
COMMENT => 'One time job to remove temporary payroll file entries'
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
JOB_NAME => 'Remove_TTbID__JOB',
ARGUMENT_POSITION => 1,
ARGUMENT_VALUE => employee_id
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
JOB_NAME => 'Remove_TTbID__JOB',
ARGUMENT_POSITION => 2,
ARGUMENT_VALUE => SYSTIMESTAMP
);
DBMS_SCHEDULER.ENABLE( 'Remove_TTbID__JOB' );
I've an Oracle job defined as follows:
BEGIN
DBMS_SCHEDULER.drop_job('clean_journal_partitions');
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'clean_journal_partitions',
job_type => 'STORED_PROCEDURE',
job_action => 'CLEAN_JOURNAL_PARTITION',
repeat_interval => 'FREQ=WEEKLY;BYDAY=MON',
auto_drop => FALSE);
DBMS_SCHEDULER.ENABLE('clean_journal_partitions');
END;
That if I'm not wrong, it should be executed once a week every monday. The problem is that it is executed only once and I don't know why.
To be able to test it more easily, I've modified it to change the frequency from weekly to every 10 seconds, like this:
BEGIN
DBMS_SCHEDULER.drop_job('clean_journal_partitions');
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'clean_journal_partitions',
job_type => 'STORED_PROCEDURE',
job_action => 'CLEAN_JOURNAL_PARTITION',
repeat_interval => 'FREQ=SECONDLY;INTERVAL=10',
auto_drop => FALSE);
DBMS_SCHEDULER.ENABLE('clean_journal_partitions');
END;
And I've the same problem. It is executed only once. Any hint why the job is not executed every 10 seconds?
This works fine for me in Oracle 11g:
CREATE TABLE TEST(
run_time DATE
);
CREATE OR REPLACE PROCEDURE CLEAN_JOURNAL_PARTITION AS
BEGIN
INSERT INTO TEST VALUES(SYSDATE);
COMMIT;
END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'clean_journal_partitions',
job_type => 'STORED_PROCEDURE',
job_action => 'CLEAN_JOURNAL_PARTITION',
repeat_interval => 'FREQ=SECONDLY;INTERVAL=10',
auto_drop => FALSE);
DBMS_SCHEDULER.ENABLE('clean_journal_partitions');
END;
I get one entry in the TEST table every 10 seconds. Your problem must be in your CLEAN_JOURNAL_PARTITION procedure, maybe it crashes?