首页 > 数据库 > Oracle > Oracle Job
1、Oracle Job主要用于定时运行PL/SQL Block
2、Oracle Job执行过程:Oracle调度器调用后台进程CJQ0,后台进程CJQ0检测job$表,检测是否有job需要执行,如果有的话,调用Jnnn进程,执行job。
3、参数JOB_QUEUE_PROCESS = n, n范围为0~36,当此参数设置为0时,CJQ0进程Stop.
4、相关表和视图:DBA_JOBS、ALL_JOBS、USER_JOBS、DBA_JOB_RUNNING,创建脚本为catjobq.sql, 包DBMS_JOB创建脚本为dbmsjob.sql
5、相关方法:
创建一个Job,自动分配job号
DBMS_JOB.SUBMIT(job OUT BINARY_INTEGER,
what IN VARCHAR2,
next_date IN DATE DEFAULT SYSDATE,
interval IN VARCHAR2 DEFAULT ‘null’,
no_parse IN BOOLEAN DEFAULT FALSE);
创建一个job,手动分配job号
DBMS_JOB.ISUBMIT(job IN BINARY_INTEGER,
what IN VARCHAR2,
next_date IN DATE DEFAULT SYSDATE,
interval IN VARCHAR2 DEFAULT ‘null’,
no_parse IN BOOLEAN DEFAULT FALSE);
更改job
DBMS_JOB.CHANGE(job IN BINARY_INTEGER,
what IN VARCHAR2,
next_date IN DATE,
interval IN VARCHAR2);
更改job的执行间隔
DBMS_JOB.INTERVAL(job IN BINARY_INTEGER,
interval IN VARCHAR2);
指定job下次执行的时间
DBMS_JOB.NEXT_DATE(job IN BINARY_INTEGER,
next_date IN DATE);
修改job的执行内容
DBMS_JOB.WHAT(job IN BINARY_INTEGER,
what IN VARCHAR2);
删除job
DBMS_JOB.REMOVE(job IN BINARY_INTEGER);
暂挂job
DBMS_JOB.BROKEN(job IN BINARY_INTEGER,
broken IN BOOLEAN,
next_date IN DATE DEFAULT SYSDATE);
运行job
DBMS_JOB.RUN(job IN BINARY_INTEGER);
导出job
DBMS_JOB.USER_EXPORT(job IN BINARY_INTEGER,
mycall IN OUT VARCHAR2);
6、测试
测试1:
目的:测试Oracle job多久检测一次。
过程:
创建一个表
create table TEST1
(
ID NUMBER,
NAME VARCHAR2(50),
TIME DATE
);
创建一个Procedure
CREATE OR REPLACE PROCEDURE bmc_Test
IS
BEGIN
INSERT INTO test1 VALUES(1,'A',SYSDATE);
dbms_lock.sleep(2);
COMMIT;
END;
创建一个job
DECLARE
job_no NUMBER;
BEGIN
dbms_job.submit(job_no,
'bmc_test;',
SYSDATE,
'sysdate + 3.5/24/60/60');
dbms_output.put_line('job_no = ' || job_no);
END;
通过查询表test1中的数据,每5s插入一条数据。
把job的间隔设置为1s
dbms_job.interval(243889,’sysdate + 1/24/60/60’);
通过查询表test1中的数据,每5s插入一条数据。
结论:因为job是通过Oracle调度器调用CJQ0进程检测是否有job需要执行,所以可能是Oracle调度器每5s启用一次CJQ0进程。
测试2:测试当job运行时间大于interval时的情况
创建一个表
create table TEST2
(
ID NUMBER,
NAME VARCHAR2(50),
TIME DATE
);
创建一个Procedure
CREATE OR REPLACE PROCEDURE bmc_Test1
IS
BEGIN
INSERT INTO test2 VALUES(1,'A',SYSDATE);
dbms_lock.sleep(70);
COMMIT;
END;
创建一个job
DECLARE
job_no NUMBER;
BEGIN
dbms_job.submit(job_no,
'bmc_test;',
SYSDATE,
'sysdate + 50/24/60/60');
dbms_output.put_line('job_no = ' || job_no);
END;
通过查询表test2的数据,发现每70s插入一条数据,而且job一直在running,所以在这种情况下,在50s时,CJQ0是检测到job需要执行,但是不会终止job,而是等到job运行完后再执行。
遗留问题:1、job每5s才会被检测,是否是因为Oracle调度器每5s调用一次CJQ0进程?
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28268054/viewspace-1101750/ ,如需转载,请注明出处,否则将追究法律责任。