Oracle 调度程序(scheduler)摘自一位大神

在11g中,Oracle提供了一个新建的Scheduler特性,帮助将作业实现自动化。它还可以帮助你控制资源的利用与并可以将数据库中的作业按优先顺序执行。传统的dbms_jobs的一个限制是它只能调度基于PL/SQL的作业,不能用来调度操作系统的可执行文件或脚本。

Scheduler包括如下权限:

scheduler_admin角色包含所有的scheduler系统权限,授权如下:

SQL> grant scheduler_admin to djp01

2  /

Grant succeeded.

SQL>

manage scheduler系统权限允许做以下工作:‘

创建、删除和更改作业类,窗口和窗口组。

停止作业

提前启动和停止窗口(关于这些部件在下文中进行介绍)。

授权如下:

SQL> grant manage scheduler to djp01

2  /

Grant succeeded.

SQL>

create job系统权限允许做如下工作:

创建作业(job)、进度表(schedule)、程序(program)、链(chain)和事件(event)。

(关于这些部件在下文中会进行介绍),授权如下:

SQL> grant create job to djp01

2  /

Grant succeeded.

SQL>

如果要执行的程序在不同的模式下,那么必要拥有执行相应模式下的程序的执行权限,如下execute any procedure。

Scheduler包括如下基本部件:

(1)作业(job)

作业是一个计划执行一次或多次的任务。例子如下:

SQL> alter session set nls_date_format = ‘yyyy-mm-dd hh24:mi:ss‘

2  /

Session altered.

SQL> alter session set nls_timestamp_tz_format = ‘yyyy-mm-dd hh24:mi:ss.ff‘

2  /

Session altered.

SQL> alter session set nls_timestamp_format = ‘yyyy-mm-dd hh24:mi:ss.ff‘

2  /

Session altered.

SQL>

说明:在使用调度程序时,会涉及一些时间的相关信息,我这里进行一些时间格式的设置方便使用。

SQL> create table emp_bak

2  as

3  select *

4  from employees

5  where 1 = 0

6  /

Table created.

SQL>

SQL> begin

2     dbms_scheduler.create_job(

3        job_name=>‘test_job‘,

4        job_type=>‘PLSQL_BLOCK‘,

5        job_action=>‘insert into emp_bak select * from employees where rownum <= 200;‘,

6        start_date=>‘2012-12-09 14:40:00‘,

7        repeat_interval=>‘FREQ=DAILY;INTERVAL=2‘,

8        end_date=>‘2012-12-09 20:00:00‘,

9        comments=>‘insert old employees into the emp_bak table‘,

10        auto_drop=>false,

11        enabled=>true);

12  end;

13  /

PL/SQL procedure successfully completed.

SQL>

说明:job_name指定作业的名称;job_type指定要创建的作业的类型,其值包括PLSQL_BLOCK(PL/SQL块),STORED_PROCEDURE(存储过程),EXECUTABLE(可执行文件或Java程序)。job_action指定作业要执行过程,命令或脚本。start_date与end_date指定作业的启动与结束时间。comments用于给当前作业添加注释。enabled指定创建作业时,是否启动或禁用作业,默认值为false,表示禁用;值为true,表启用。auto_drop指定该作业执行完成后,是否自动将其删除,默认值为true,表示执行完成后自动删除该作业。repeat_interval指定作业执行的频率,FREQ=DAILY;INTERVAL=2表示每天运行一次该作业。该值是一个日历表达式(calendaring expression)由三个部分组成,Frequency: 这是表达式必须包含的部分,用FREQ指定,可能取的值为YEARLY,MONTHLY,WEEKLY,DAILY,HOURLY,MINUTELY和SECONDLY。repeat interval:这个时间间隔由INTERVAL关键字标识,表示执行的频率。specific:提供一个作业何时运行的详细信息,可能取值为:BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY,BYHOUR,BYMINUTE和BYSECOND。例如:BYMONTHDAY表示每月的某一天,BYDAY表示每周的某一天。以下是典型的日历表达式:

FREQ=DAILY;INTERVAL=3;每三天执行一次。

FREQ=HOURLY;INTERVAL=2;每隔一小时执行一次。

FREQ=WEEKLY,BYDAY=SUN;每个星期日执行一次。

FREQ=WEEKLY;INTERVAL=2,BYDAY=FRI;每隔一周的周五执行一次。

FREQ=MONTHLY;BYMONTHDAY=1;每月最后一天执行一次。

FREQ=MINUTELY;INTERVAL=30;每半个小时执行一次。

下面我们看一下执行的情况:

SQL> select count(*)

2  from emp_bak

3  /

COUNT(*)

----------

200

SQL>

上述调度程序的作业成功运行,下面我们看一些该作业的信息:

SQL> select job_style,job_type,job_action,program_name,state

2  from dba_scheduler_jobs

3  where job_name = upper(‘test_job‘)

4  /

JOB_STYLE              JOB_TYPE

---------------------- --------------------------------

JOB_ACTION

--------------------------------------------------------------------------------

PROGRAM_NAME

--------------------------------------------------------------------------------

STATE

------------------------------

REGULAR                PLSQL_BLOCK

insert into emp_bak select * from employees where rownum <= 200;

COMPLETED

SQL>

状态显示,该作业执行完成,该作业的类型为REGULAR(规律性的)。

作业的其他一些管理:

禁用一个作业:

SQL> exec dbms_scheduler.disable(‘test_job‘);

PL/SQL procedure successfully completed.

SQL>

激活一个作业:

SQL> exec dbms_scheduler.enable(‘test_job‘);

PL/SQL procedure successfully completed.

SQL>

运行一个作业:

SQL> truncate table emp_bak;

Table truncated.

SQL> exec dbms_scheduler.run_job(‘test_job‘);

PL/SQL procedure successfully completed.

SQL> select count(*)

2  from emp_bak

3  /

COUNT(*)

----------

200

SQL>

说明:该运行相当于是手工执行一次相应的程序。

停止一个作业:

SQL> exec dbms_scheduler.stop_job(‘test_job‘);

如果一个作业不在运行状态,它将会出现ORA-27366错误。

删除一个作业:

SQL> exec dbms_scheduler.drop_job(‘test_job‘);

PL/SQL procedure successfully completed.

SQL>

(2)进度表(schedule)

进度表是数据库执行一个作业的时间及频率的说明。假如有一些作业都是在大致相同的时间内运行的,那么,可以使用一个进度表,可以化这些作业的创建与管理。例子如下:

SQL> begin

2     dbms_scheduler.create_schedule(

3        schedule_name=>‘test_schedule‘,

4        start_date=>systimestamp,

5        repeat_interval=>‘FREQ=MINUTELY;INTERVAL=30‘,

6        end_date=>systimestamp+3,

7        comments=>‘Every 30 minute‘);

8  end;

9  /

PL/SQL procedure successfully completed.

SQL>

下面我们查看该进度表的创建信息:

SQL> select start_date,end_date,schedule_type

2  from dba_scheduler_schedules

3  where schedule_name = upper(‘test_schedule‘)

4  /

START_DATE

---------------------------------------------------------------

END_DATE

---------------------------------------------------------------

SCHEDULE_TYPE

----------------

2012-12-09 17:22:43.781000

2012-12-12 17:22:43.000000

CALENDAR

SQL>

可以对已经创建的进度表进行相关属性的更改,如下:

SQL> begin

2     dbms_scheduler.set_attribute(

3        name=>‘test_schedule‘,

4        attribute=>‘start_date‘,

5        value=>systimestamp);

6  end;

7  /

PL/SQL procedure successfully completed.

SQL>

对已经有的进度表,我们可以进行删除,如下:

SQL> exec dbms_scheduler.drop_schedule(‘test_schedule‘);

PL/SQL procedure successfully completed.

SQL>

(3)程序(program)

程序包括关于一个scheduler作业的元数据。程序包括程序名,程序类型以及程序的动作。它是一个过程或是可执行脚本的实际名称。例子如下:

SQL> begin

2     dbms_scheduler.create_program(

3        program_name=>‘test_program‘,

4        program_type=>‘STORED_PROCEDURE‘,

5        program_action=>‘auto_archive_emp‘,

6        enabled=>true,

7        comments=>‘use to execute the procedure of auto_archive_emp‘);

8  end;

9  /

PL/SQL procedure successfully completed.

SQL>

说明:program_type与program_action同上述的job_type,job_action含义一样,这里不再说明。enabled表示该程序是否被启用,默认值为false,表示禁用。

我们可以用如下的方法对程序进行启用或禁用:

禁用一个程序:

SQL> exec dbms_scheduler.disable(‘test_program‘);

PL/SQL procedure successfully completed.

SQL>

启用一个程序:

SQL> exec dbms_scheduler.enable(‘test_program‘);

PL/SQL procedure successfully completed.

SQL>

同样,我们也可以进行删除,如下:

SQL> exec dbms_scheduler.drop_program(‘test_program‘);

PL/SQL procedure successfully completed.

SQL>

对程序相关信息的查看可以使用dba_scheduler_programs数据字典。

(4)链(chain)

可以使用调度程序链的概念将相关的程序链接在一起。因此,一个程序的成功运行,可能是以另外的程序成功运行为基础;还可以是基于一个键而非程序启动作业。链中连续的位置称为链的“步骤(step)”,每个步骤指向另一个链,程序或事件。由于链使用Oracle Streams Rules Engine(Oracle流规则引擎对象)。因此用户必须具有create job 和Rules Engine权限才能创建一个链。例子如下:

进行如下授权:

SQL> begin

2     dbms_rule_adm.grant_system_privilege(

3        dbms_rule_adm.create_rule_obj,‘djp01‘);

4     dbms_rule_adm.grant_system_privilege(

5        dbms_rule_adm.create_rule_set_obj,‘djp01‘);

6     dbms_rule_adm.grant_system_privilege(

7        dbms_rule_adm.create_evaluation_context_obj,‘djp01‘);

8  end;

9  /

PL/SQL procedure successfully completed.

SQL>

创建如下:

SQL> begin

2     dbms_scheduler.create_chain(

3        chain_name=>‘test_chain‘,

4        comments=>‘A shain test‘);

5  end;

6  /

PL/SQL procedure successfully completed.

SQL>

定义链步骤:

SQL> begin

2     dbms_scheduler.define_chain_step(

3        chain_name=>‘test_chain‘,

4        step_name=>‘test_step1‘,

5        program_name=>‘test_program1‘);

6     dbms_scheduler.define_chain_step(

7        chain_name=>‘test_chain‘,

8        step_name=>‘test_step2‘,

9        program_name=>‘test_program2‘);

10  end;

11  /

PL/SQL procedure successfully completed.

SQL>

说明:链步骤可以指向一个程序、链或事件。使用不同的参数进行标识。

为了使用链有效的运行,必须给链添加规则,用于确定步骤何时运行并指定运行条件。如下:

SQL> begin

2     dbms_scheduler.define_chain_rule(

3        chain_name=>‘test_chain‘,

4        condition=>‘true‘,

5        action=>‘start test_step1‘);

6     dbms_scheduler.define_chain_rule(

7        chain_name=>‘test_chain‘,

8        condition=>‘test_step1 completed‘,

9        action=>‘start test_step2‘);

10     dbms_scheduler.define_chain_rule(

11        chain_name=>‘test_chain‘,

12        condition=>‘test_step2 completed‘,

13        action=>‘end‘);

14  end;

15  /

PL/SQL procedure successfully completed.

SQL>

说明:在规则中,我们按照每一步的先后顺序进行定义。如果每个步骤中都事务的先后关系,使用链是一个不错的选择。

在上述步骤完成之后,我们还需要对链进行启用,如下:

SQL> exec dbms_scheduler.enable(‘test_chain‘);

PL/SQL procedure successfully completed.

SQL>

这时,我们就可以在作业(job)中使用该链了(job_type指定为chain,job_action指定对应链的名称,如test_chain)。

我们还可以使用如下方式运行:

SQL> begin

2     dbms_scheduler.run_chain(

3        chain_name=>‘test_chain‘,

4        start_steps=>‘test_step1,test_step2‘);

5  end;

6  /

PL/SQL procedure successfully completed.

SQL>

(5)事件(event)

Scheduler使用Oracle Stream Advanced Qeueing(Oracle流高级队列)触发事件并启动基于事件的数据库作业。事件是一个应用程序或是进程注意到某个事件或动作时发出的一条消息。有两种类型的事件:Scheduler引发的事件和应用程序引发的事件。Scheduler引发的事件由Scheduler运行中的变化而导致,比如Scheduler作业成功完成是一个事件。应用程序引发的事件由Scheduler为启动一个作业而使用或是消费。

使用基于事件的作业,只要在create_job过程上指定event_condition与queue_spec即可。但是事件的定义涉及到了,dbms_aqadm程序包的一些使用。我查看了dbms_aqadm包的声明,没有相关的注释,之后试了几次,没有达到效果,这个问题有待解决。

下面我们来看几个综合使用的例子:

SQL> begin

2     dbms_scheduler.create_job(

3        job_name=>‘test_job1‘,

4        program_name=>‘test_program1‘,

5        schedule_name=>‘test_schedule‘,

6        enabled=>true,

7        auto_drop=>false,

8        comments=>‘use program and schedule to create job‘);

9  end;

10  /

PL/SQL procedure successfully completed.

SQL>

说明:在上述作业的创建中,我使用了程序与进度表。如果要进行调整,可以调整相应的程序与进行度即可。

SQL> begin

2     dbms_scheduler.create_job(

3        job_name=>‘test_job2‘,

4        schedule_name=>‘test_schedule‘,

5        job_type=>‘chain‘,

6        job_action=>‘test_chain‘,

7        enabled=>true,

8        auto_drop=>false,

9        comments=>‘use chain to create job‘);

10  end;

11  /

PL/SQL procedure successfully completed.

SQL>

说明:在创建job时,我们两样也可以指定一个链。如果要指定链,那么job_type为chain,job_action为所创建的链名。

时间: 2024-10-13 11:05:40

Oracle 调度程序(scheduler)摘自一位大神的相关文章

弄了三个星期了,不好意思了~~无奈求助于众位大神!

最近在弄一个示波器,要求是用c++读出示波器所捕获波形的数据.根据提供的例程FORMATIO.cpp,我修改了资源地址后运行,在进入ReadWaveform(ViSession vi, long* elements)函数,读取     // Get width of element field.status = viScanf(vi, "%c", &c);if (status < VI_SUCCESS) goto error;assert(c >= '0' &

[Linux]运维三十六计--腾讯两位大神的总结

这里是腾讯两位大神梁定安.周小军总记得运维DBA三十六计,So有道理

sed命令如何实现XML文件的增删改??急急急!哪位大神告诉下啊

<DC_Public>    < Codec_Space Codec_SpaceValue="0" />    < HeartBeatCfg HeartBeatRate="16" Mux_HB_DECount="2" Codec_HB_DECount="2" Prov_HB_DECount="2" />    < DC_Public PathValue="

另一位大神关于crash的博文

原文地址:http://www.cnblogs.com/tianlin106/p/3928596.html 作为一名应用开发者,你是否有过如下经历?为确保你的应用正确无误,在将其提交到应用商店之前,你必定进行了大量的测试工作.它在你的设备上也运行得很好,但是,上了应用商店后,还是有用户抱怨会闪退 !如果你跟我一样是个完美主义者,你肯定想将应用做到尽善尽美.于是你打开代码准备修复闪退的问题--但是,从何处着手呢?这时iOS崩溃日志派上用场了.在大多数情况下,你能从中了解到关于闪退的详尽.有用的信息

(16)mongodb mapReduce分布式统计示例遇到的一个未解问题,求平均值不对,希望哪位大神给指点一下

mapReduce 的优势在于分布式,这一节记录一个分布式统计的示例,整个过程分为这几步:启动分布式服务.手动分片.导入数据.执行 mapReduce.下面单独说说这几步. 1.启动分布式服务 参考前面的第10节和第11节,不在重复说了. 2.手动分片: sh.enableSharding('test'); 用test库做分片 sh.shardCollection('test.dz',{sn:1}); 指定片键,test库的dz集合,sn为片键 mongos> for(var i=1;i<=8

哪位大神尤模拟均衡的软件

http://www.nanpinjie.com/activity/detail/153669 http://www.nanpinjie.com/activity/detail/153638 http://www.nanpinjie.com/activity/detail/153607 http://www.nanpinjie.com/activity/detail/153566 http://www.nanpinjie.com/activity/detail/153537 http://www

哪位大神麻烦看下 ,ParameterizedType为什么会转换异常呢?

这是个是工具类:  public class ConverUtils<T,E>  {     public T converObject(E e){         ObjectMapper objectMapper=new ObjectMapper();         ParameterizedType param = (ParameterizedType)this.getClass().getGenericSuperclass();         Class type = (Class

Arcgis怎么区分加载的是矢量还是切片地图?哪位大神有切片地图网址给我一个,谢谢。。。

============问题描述============ RT,我现在用的好像是矢量地图,加载后移动屏幕范围,之前加载好的也会重新被加载,十分慢,用户体验十分不好.是不是换成切片地图就好了.我可以再客户端将矢量地图变成切片地图么?还是只能接受切片地图资源才行... ============解决方案1============ 你看看加载的时候是不是一小个方格一小个方格加载的~是的话就是切片吧~ ============解决方案2============ 切片也慢,离线最好...不过切片本地缓存的话

谋哥:大神都是这么练出来的--打一个5厘米口径的洞,打进去10米!

[每天一原创干货,第六十六篇] 我不是说我帅了! 昨天一位大神(他在自己的领域早就成神)答应我写一篇文章描述他的帅,就分享一个价值3万的江湖技法.他要求不能暴露它名字.头像,这个有难度,不过我答应他,就为了那价值3万的神技! 大家都知道,百度知道的回答是不能带超链接的!但是,为啥说人家帅?那是这位帅神能够玩到带几十个超链接.百度都怕他,所以在百度知道这个领域他是超神的存在.今天他免费教谋哥和其他牛人这个技法,当然了,我们是一个圈子的.圈子名字,我就不告诉你了. 先截图看一般情况下,带超链接的百度