在Oracle开发中,经常需要对一些任务进行调度。在Oracle中,调度任务又称为作业,只要是使用DBMS_JOB
包来实现的。
创建作业SUBMIT
这个过程用来创建一个作业,并且输出作业号码。当建立新的作业时,需要给出作业要执行的操作,作业在下一次运行的日期及运行的时间间隔,语法如下:
PROCEDURE 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, -- 是否解析与作业相关的例程
instance IN BINARY_INTEGER DEFAULT 0, -- 指定哪个例程可以运行作业
force IN BOOLEAN DEFAULT False -- 是否强制运行与作业相关的例程
);
举个例子,DBMS_DDL.ANALYZE_OBJECT
可以分析数据表,并且将存储结果存储起来,对于SQL的运行效率有较大的提升,大多数DBA经常需要用到这个过程来进行性能优化,因此会将其定义为一个作业来每日运行一次,实现代码如下:
DECLARE
v_jobno NUMBER;
BEGIN
DBMS_JOB.submit
(v_jobno, --作业编号
--作业执行的过程
'DBMS_DDL.analyze_object(''TABLE'',''SCOTT'',''EMP'',''COMPUTE'');',
--下一次执行的日期
SYSDATE,
--执行的时间间隔,表示24小时。
'SYSDATE+1'
);
DBMS_OUTPUT.put_line('获取的作业编号为:'||v_jobno); --输出作业编号
COMMIT;
END;
在创建了作业后,可以通过user_jobs
数据字典来查询创建的作业。
这里要说一下,interval参数是VARCHAR2类型,不是一个日期或天或分钟的数字,例如:
‘SYSDATE+1’:表示每天的当前时间运行
‘TRUNC(SYSDATE)+1’:表示每天的0点运行
‘TRUNC(SYSDATE)+17/24’:表示在每天下午5点运行
‘null’:表示作业立即运行,运行完退出,不重复运行
移除作业REMOVE
该过程用于移除在队列中的某个作业,当前运行的作业不受影响,即使删除的作业不再执行,依然会执行完毕,只是后续不会再次执行。用户只能删除属于自己的作业。
DBMS_JOB.REMOVE(job IN BINARY_INTEGER);
比如想删除作业22904,代码这样写:
EXECUTE DBMS_JOB.REMOVE(22904);
更改作业 CHANGE
CHANGEG用来改变已提交作业的一些设置的参数,语法如下:
DBMS_JOB.CHANGE(job OUT BINARY_INTEGER,
What IN VARCHAR2,
next_date IN DATE DEFAULT SYSDATE,
interval IN VARCHAR2 DEFAULT NULL,
instance IN BINARY_INTEGER DEFAULT 0,
force IN BOOLEAN DEFAULT False
);
参数的含义与SUBMIT基本相同,如果参数what,next_date,interval
为NULL,则保持以前的值不变。用户只能修改自己的作业。
比如想要把作业22904改为每两天执行一次,则:
DBMS_JOB.CHANGE(22904, NULL, NULL, 'SYSDATE + 2');
更改作业执行WHAT
用于改变指定作业执行的PL/SQL代码。
DBMS_JOB.WHAT(job IN BINARY_INTEGER, what IN VARCHAR2);
更改运行日期NEXT_DATE
DBMS_JOB.NEXT_DATE(job IN BINARY_INTEGER, next_date IN DATE);
数据库实例配置INSTANCE
该过程用于更改执行的数据库实例的配置。
DBMS_JOB.INSTANCE(job IN BINARY_INTEGER,
instance IN BINARY_INTEGER,
force IN BOOLEAN DEFAULT False);
instance为指定提交作业 到指定的数据库的实例。
更改间隔INTERVAL
DBMS_JOB.INTERVAL(job IN BINARY_INTEGER, interval IN VARCHAR2);
中断做业BROKEN
用于标记作业中断或非中断,中断作业将不再被执行,Oracle不会试图去执行一个标记为中断的作业,但是用户可以通过调用DBMS_JOB.RUN
过程强制执行一个标记为中断的作业。
DBMS_JOB.BROKEN(job IN BINARY_INTEGER,
broken IN BOOLEAN,
next_date IN DATE DEFAULT SYSDATE);
比如要将作业22904标记为中断,并执行下一次的执行时间为下个星期一:
DBMS_JOB.BROKEN(22904, False, NEXT_DATE(SYSDATE, 'MONDAY'));
强制作业运行RUN
使用RUN可以强制作业立即执行,即使作业已标记为中断。因为作业在运行完后会计算下一次执行的时间,因此在调用RUN之后,下一次的执行时间也会发生改变。语法 如下:
DBMS_JOB.RUN(job IN BINARY_INTEGER, force IN BOOLEAN DEFAULT False);
force参数为True时,作业 执行优化配置无效,如果为False,则作业必须在指定的数据库实例中运行。