--创建一个简单的job
为大家演示一个每分钟向指定表里插入数据的job
--创建测试表
SQL> create table aspen_job_tb(id number(10),i_date date);
表已创建。
--创建job要调用的过程
SQL> create or replace procedure job_pro
2 as
3 begin
4 insert into aspen_job_tb values(15,sysdate);
5 end;
6 /
过程已创建。
--创建过程
dbms_job.submit的主要参数有四个
job 这是一个out参数 用来接收返回来的job编号,这个job的唯一标识
what 指明job要执行的pl/sql块名称注意要加分号哦 'job_pro;'
next_date job何时运行
interval job执行的间隔时间
SQL> var test_job number;
SQL> begin
2 sys.dbms_job.submit(job=>:test_job,
3 what=>'job_pro;',
4 next_date=>to_date('20110615 10:30:00','yyyymmdd hh24:mi:ss'),
5 interval=>'sysdate+1/1440');
6 commit;
7 end;
8 /
PL/SQL 过程已成功完成。
--查询下表里的数据 看看job的执行效果
SQL> select * from aspen_job_tb;
ID I_DATE
---------- -----------------
15 20110615 10:30:04
15 20110615 10:31:04
--可以通过dba_jobs、user_jobs、all_jobs、dba_jobs_running(包含正在运行job相关信息)查看job的运行情况
last_date job上次成功执行的时间
this_date job正在执行的时间(如果查询时job正在执行则有值)
next_date job下次执行的时间(受last_date和interval的影响)
total_time job运行的总时间(每次运行的时间累加)
SQL> col what format a10;
SQL> col interval format a15;
SQL> select job,last_date,this_date,next_date,total_time,what,broken,interval
2 from user_jobs
3 where what='job_pro;';
JOB LAST_DATE THIS_DATE NEXT_DATE TOTAL_TIME WHAT BROKEN INTERVAL
---------- ----------- ----------- ----------- ---------- ---------- ------ ---------------
50 2011-6-15 1 2011-6-15 1 0 job_pro; N sysdate+1/1440
job如果由于某种原因未能成功之行,oracle将重试16次后,还未能成功执行,将被标记为broken
--立即执行job
SQL> exec dbms_job.run(50);
PL/SQL 过程已成功完成。
执行类似的命令要以job的所有者来执行否则你将会得到如下错误提示
SQL> exec dbms_job.run(50); --以sys用户都不行
begin dbms_job.run(50); end;
ORA-23421: 作业编号50在作业队列中不是一个作业
ORA-06512: 在 "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: 在 "SYS.DBMS_IJOB", line 680
ORA-06512: 在 "SYS.DBMS_JOB", line 261
ORA-06512: 在 line 1
--暂停一个job(下次重启实例是还是会执行)
此过程的3个参数
job BINARY_INTEGER 指明哪个job需要被暂停
broken BOOLEAN true标记为暂停,false未暂停
NEXT_DATE DATE 什么执行执行这个过程 默认值为sysdate
SQL> exec dbms_job.broken(50,true);
PL/SQL 过程已成功完成。
--利用dbms_job.change()来改变一个现有job
主要参数
JOB BINARY_INTEGER
WHAT VARCHAR2
NEXT_DATE DATE
INTERVAL VARCHAR2
--创建一个新的过
SQL> create or replace procedure job_pro2
2 as
3 begin
4 insert into aspen_job_tb values(16,sysdate);
5 end;
6 /
过程已创建。
--改变job
SQL> begin
2 dbms_job.change(50,'job_pro2;',sysdate,'sysdate+1/1440');
3 end;
4 /
PL/SQL 过程已成功完成。
--查询job的信息
SQL> select job,last_date,this_date,next_date,total_time,what,broken,interval
2 from user_jobs
3 where job=50;
JOB LAST_DATE THIS_DATE NEXT_DATE TOTAL_TIME WHAT BROKEN INTERVAL
---------- ----------- ----------- ----------- ---------- ---------- ------ ---------------
50 2011-6-15 1 2011-6-15 1 178 job_pro; N sysdate+1/1440
--发现job的what没有变化还是job_pro 而不是job_pro2
原因是我们在执行change()过程是没有commit;
手动commit下再来查询 结果ok
在oracle中执行过程是不需要commit的但是……
SQL> select job,last_date,this_date,next_date,total_time,what,broken,interval
2 from user_jobs
3 where job=50;
JOB LAST_DATE THIS_DATE NEXT_DATE TOTAL_TIME WHAT BROKEN INTERVAL
---------- ----------- ----------- ----------- ---------- ---------- ------ ---------------
50 2011-6-15 1 2011-6-15 1 408 job_pro2; N sysdate+1/1440
--更改job的what
除了change()可以更改what外 dbms_job.what是专门用户更改job的what的
参数名称 类型 输入/输出
------------------------------ ----------------------- ------
JOB BINARY_INTEGER IN
WHAT VARCHAR2 IN
SQL> begin
2 dbms_job.what(50,'job_pro;');
3 commit; --别忘了commit哦
4 end;
5 /
PL/SQL 过程已成功完成。
SQL> select job,last_date,this_date,next_date,total_time,what,broken,interval
2 from user_jobs
3 where job=50;
JOB LAST_DATE THIS_DATE NEXT_DATE TOTAL_TIME WHAT BROKEN INTERVAL
---------- ----------- ----------- ----------- ---------- ---------- ------ ---------------
50 2011-6-15 1 2011-6-15 1 408 job_pro; N sysdate+1/1440
此外更改interval也有dbms_job.interval()
参数名称 类型 输入/输出
------------------------------ ----------------------- ------
JOB BINARY_INTEGER IN
INTERVAL VARCHAR2 IN
--删除job
dbms_job.remove()
参数名称 类型 输入/输出
------------------------------ ----------------------- ------
JOB BINARY_INTEGER IN
SQL> exec dbms_job.remove(50);
PL/SQL procedure successfully completed
SQL> commit;
Commit complete
SQL> select job,last_date,this_date,next_date,total_time,what,broken,interval
2 from user_jobs
3 where job=50;
JOB LAST_DATE THIS_DATE NEXT_DATE TOTAL_TIME WHAT BROKEN INTERVAL
---------- ----------- ----------- ----------- ---------- ---------- ------ ---------------