I have created a package purging inside that created procedure. How to schedule procedure around 2AM CST?
create or replace package body purging as
PROCEDURE del_exp IS
begin
FOR td IN (
SELECT
table_name
FROM
all_tables
where owner = 'ud_oi' and table_name not like 'lgh%'
)
LOOP
EXECUTE IMMEDIATE 'DELETE FROM ' || td.table_name || ' WHERE TRUNC(case_dt) < TRUNC(sysdate - 38)' ;
END LOOP;
end;
END del_exp;
A simple option is to use DBMS_JOB; if your database is recent, DBMS_SCHEDULER is preferred. You'd do it as follows:
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT (
job => X,
what => 'begin purging.del_exp; end;',
next_date => TO_DATE ('16.06.2020 02:00:00', 'dd/mm/yyyy hh24:mi:ss'),
interval => 'TRUNC (SYSDATE+1) + 2 / 24',
no_parse => FALSE);
SYS.DBMS_OUTPUT.PUT_LINE ('Job Number is: ' || TO_CHAR (x));
COMMIT;
END;
/
A DBMS_SCHEDULER option (which also shows how to run it during working days (at least, working here where I live)):
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'purging',
job_type => 'PLSQL_BLOCK',
job_action => 'begin purging.del_exp; end;',
start_date => TO_TIMESTAMP_TZ ('16.06.2020 02:00 Europe/Zagreb',
'dd.mm.yyyy hh24:mi TZR'),
repeat_interval => 'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=2; BYMINUTE=0',
enabled => TRUE,
comments => 'Purge tables');
END;
/
Just to mention: condition you wrote:
table_name not like 'lgh%'
looks suspicious. Table names are - by default - in UPPERCASE. Unless you create tables using mixed (or lower) case, you can do that by enclosing their names into double quotes. I hope you didn't/don't do that. Therefore, you'd rather use
table_name not like 'LGH%'
Related
Calling the package inside the job gives an Error report -
ORA-06550: line 8, column 5:
PLS-00103: Encountered the symbol "
);
end; : AUXSQLDBIND4: = SqlDevBind1Z_1; : AUXSQLDBIND3: = SqlDevBind1Z_2; : AUXSQLDBIND2: = SqlDevBind1Z_3; : AUXSQLDBIND1: = SqlDevBind "
Help call the packet with the passed variable work_date for a certain calculation for each day of the month.
Thanks in advance for your help!
DBMS_SCHEDULER.create_job (
job_name => 'J_ACCOUNT_TURNOVER_F',
job_type => 'PLSQL_BLOCK',
start_date => SYSTIMESTAMP, enabled => TRUE,
job_action =>
'declare
start_date number;
end_date number;
work_date date;
begin
start_date := to_number(to_char(to_date('2018-01-01', 'yyyy-MM-dd'), 'j'));
end_date := to_number(to_char(to_date('2018-01-31', 'yyyy-MM-dd'), 'j'));
for cur_r in start_date..end_date loop
work_date := to_char(to_date(cur_r, 'j'), 'yyyyMMdd');
dma.fill_account_turnover_f.fill(work_date);
end loop;
end;'
);
end;
Wouldn't it be simpler if you created a stored procedure and called it, instead of embedding that anonymous PL/SQL block into DBMS_SCHEDULER.CREATE_JOB call? Now you have to escape single quotes, i.e. use two consecutive ones every time. Something like this:
begin
DBMS_SCHEDULER.create_job (
job_name => 'J_ACCOUNT_TURNOVER_F',
job_type => 'PLSQL_BLOCK',
start_date => SYSTIMESTAMP, enabled => TRUE,
job_action =>
'declare
start_date number;
end_date number;
work_date date;
begin
start_date := to_number(to_char(to_date(''2018-01-01'', ''yyyy-MM-dd''), ''j''));
end_date := to_number(to_char(to_date(''2018-01-31'', ''yyyy-MM-dd''), ''j''));
for cur_r in start_date..end_date loop
work_date := to_char(to_date(cur_r, ''j''), ''yyyyMMdd'');
dma.fill_account_turnover_f.fill(work_date);
end loop;
end;'
);
end;
/
Maybe you're allergic to stored procedures :) Here is how you can do it without having to escape each individual quote. It is called the "Q Quote syntax".
DBMS_SCHEDULER.create_job (
job_name => 'J_ACCOUNT_TURNOVER_F',
job_type => 'PLSQL_BLOCK',
start_date => SYSTIMESTAMP, enabled => TRUE,
job_action =>
q'!declare
start_date number;
end_date number;
work_date date;
begin
start_date := to_number(to_char(to_date('2018-01-01', 'yyyy-MM-dd'), 'j'));
end_date := to_number(to_char(to_date('2018-01-31', 'yyyy-MM-dd'), 'j'));
for cur_r in start_date..end_date loop
work_date := to_char(to_date(cur_r, 'j'), 'yyyyMMdd');
dma.fill_account_turnover_f.fill(work_date);
end loop;
end;'
);
end;!'
More examples in this question
I want to create a export table job, but I can't understand why its not working.
my table is Department
create table department (id number, name varchar2(200));
I want to export a csv file for per day at 9:00 pm. I need to create it.
I only know:
0. create a directory
create a PROCEDURE
create a DBMS_SCHEDULER.CREATE_PROGRAM
create a DBMS_SCHEDULER.CREATE_SCHEDULE
create a DBMS_SCHEDULER.CREATE_JOB
excute the job
thanks
Yes, you can use DBMS_SCHEDULER by creating in such a way
DECLARE
v_job_name VARCHAR2(32) := 'jb_exp_emp_data';
BEGIN
DBMS_SCHEDULER.CREATE_JOB(job_name => v_job_name,
job_type => 'STORED_PROCEDURE',
job_action => 'exp_emp_data',
start_date => TO_DATE('11-12-2021 21:00:10',
'DD-MM-YYYY HH24:MI:SS'),
repeat_interval => 'FREQ=DAILY; BYHOUR=21;',
auto_drop => false,
comments => 'Exports the content of the department table every day at 9:00PM o''clock ');
DBMS_SCHEDULER.ENABLE(v_job_name);
END;
/
that starts at the time defined by the start_date parameter, then repeats on every upcoming days at 9pm in the future.
I followed the steps below and it was successful ...
Create a directory (path of export file):
CREATE OR REPLACE DIRECTORY CSVDIR AS 'D:\';
Create a procedure:
Create Or Replace Procedure exp_emp_data Is
today varchar2(200);
fileName varchar2(200);
n_file utl_file.file_type;
v_string Varchar2(4000);
Cursor c_emp Is
Select
id, name
From
department;
Begin
select to_char(sysdate,'yyyymmdd','nls_calendar=persian') into today from dual;
fileName := 'empdata' || today || '.csv';
n_file := utl_file.fopen('CSVDIR', fileName, 'w', 4000);
v_string := 'ID, Name';
utl_file.put_line(n_file, v_string);
-- open the cursor and concatenate fields using comma
For cur In c_emp Loop
v_string := cur.id
|| ','
|| cur.name;
-- write each row
utl_file.put_line(n_file, v_string);
End Loop;
-- close the file
utl_file.fclose(n_file);
Exception
When Others Then
-- on error, close the file if open
If utl_file.is_open(n_file) Then
utl_file.fclose(n_file);
End If;
End;
/
-------- Test
Begin
exp_emp_data;
End;
/
Create a program:
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROG_EXPORT_TABLE',
program_action => 'exp_emp_data',
program_type => 'STORED_PROCEDURE');
END;
/
Create a job:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'JOB_EXPORT_TABLE',
job_type => 'STORED_PROCEDURE',
job_action => 'PROG_EXPORT_TABLE',
start_date => '16-nov-2021 11:50:00 pm',
repeat_interval => 'FREQ=DAILY;BYHOUR=23;BYMINUTE=59',
enabled => true
);
END;
/
And enabled it:
exec dbms_scheduler.enable('JOB_EXPORT_TABLE');
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 would like to launch a scheduled job after every two hours starting from 04:15 tomorrow. The job should launch everyday and after every two hours. Something like at : 04:15, 06:15, 08:15....
The procedure is about creating file in a remote machine. When I test the procedure then it works just fine, and creates file in remote location. However, it fails as a job in dbms_jobs package. I am not sure what I am doing wrong. Here is the code of procedure:
CREATE OR REPLACE PROCEDURE ARC_HRVR.VR_AD_INTEGRATION_EXPORT AS
v_file UTL_FILE.file_type;
BEGIN
v_file := UTL_FILE.fopen('DIR_VR_AD_INTEGRATION', 'HRMtoAD1_'||to_char(sysdate,'YYYYMMDD')||'_'||to_char(sysdate,'HH24MISS'), 'w', 32767);
FOR x IN (
SELECT * FROM (SELECT
decode(pid, NULL, RPAD(' ',7,' '), RPAD(user_id, 7, ' '))|| '' ||
decode(o365, NULL, RPAD(' ',80,' '), RPAD(o365, 80, ' '))
str FROM table WHERE integrated = 'N') str WHERE rownum <= 1000 ORDER BY rownum)
´LOOP
BEGIN
UTL_FILE.put_line(v_file, x.str);
END;
END LOOP;
UTL_FILE.fflush(v_file);
UTL_FILE.fclose(v_file);
END VR_AD_INTEGRATION_EXPORT;
And here is the code for launching job:
DECLARE
l_id binary_integer;
begin
dbms_job.submit(job => l_id, what => 'ARC_HRVR.vr_ad_integration_export();', interval => 'TRUNC(SYSDATE)+1+4.25/24', );
dbms_output.put_line(l_id);
end;
A bit of guidance and tweaking will fix my code :-)
Thanks in advance
Are you putting in the job as the procedure owner (ARC_HRVR) or as a user that has access to execute the code?
Have you tried surrounding the 'what' in a execution block?
begin ARC_HRVR.vr_ad_integration_export(); end;
The job is launching, right? You see next_date getting updated in the view dba_jobs, etc?
You can refer this example
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'test_full_job_definition',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN my_job_procedure; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=hourly; byminute=0; bysecond=0;',
end_date => NULL,
enabled => TRUE,
comments => 'Job defined entirely by the CREATE JOB procedure.');
END;
/
and for more detail please go through this Scheduler