基于事件的Oracle JOB概述
Oracle的任务调度不仅可以基于时间进行调度,也可以根据事件来触发。关于Oracle基于时间的调度管理可以参看http://czmmiao.iteye.com/blog/1003505
在Oracle的调度管理器里,使用高级队列(Advanced Queue)来触发事件。也就是说,可以通过应用程序向某个队列发送一个事件,从而触发某个任务执行。要创建基于事件的队列需要两个额外的信息,事件所在的队列名称以及任务触发的条件。一旦条件为真,则启动任务。在创建基于事件的Oracle JOB中会涉及到一些高级队列的知识,本文不做讨论。有兴趣的朋友可以自行查看资料
实验环境
创建一个测试用表
SQL>conn hr/hr;
Connected.
SQL> create table event_job_test(id number constraint event_job_test_pk primary key,createdate date);
Table created.
创建序列以生成该表的主键
SQL> create sequence event_job_test_seq;
Sequence created.
创建类型以存放队列里的消息格式
SQL> create or replace type event_job_test_t as object(
2 object_owner varchar2(50),event_name varchar2(50));
3 /
Type created.
创建队列表,该队列包含刚刚创建的类型 event_job_test_t所包含的属性,也就是object_owner和object_name。
SQL> begin
2 dbms_aqadm.create_queue_table(
3 queue_table=>'event_queue_tab',
4 queue_payload_type=>'event_job_test_t',
5 multiple_consumers=>true);
6 end;
7 /
PL/SQL procedure successfully completed.
创建一个队列,并将该队列于前面创建的队列表关联。
SQL> begin
2 dbms_aqadm.create_queue(
3 queue_name=>'event_queue',
4 queue_table=>'event_queue_tab');
5 end;
6 /
PL/SQL procedure successfully completed.
启动该队列
SQL> begin
2 dbms_aqadm.start_queue(queue_name=>'event_queue');
3 end;
4 /
PL/SQL procedure successfully completed.
创建基于事件的任务
1、创建Program
2、创建Schedule
其中 tab.user_data.object_owner=‘’HR‘’和tab.user_data.event_name=‘’give_me_an_event‘' 为两个单引号。表示该任务启动的条件为当队列出现消息,的object_owner属性为HR。event_name属性为give_me_an_event时就启动任务。
该JOB的SQL如下
BEGIN
sys.dbms_scheduler.create_job(
job_name => '"HR"."EVENT_BASED_JOB"',
job_type => 'PLSQL_BLOCK',
job_action => 'begin
insert into event_job_test
values(event_job_test_seq.nextval,sysdate);
end;',
event_condition => 'tab.user_data.object_owner=‘’HR‘’and
tab.user_data.event_name=‘’give_me_an_event‘’',
queue_spec => 'HR.EVENT_QUEUE',
start_date => systimestamp at time zone '+8:00',
job_class => 'DEFAULT_JOB_CLASS',
auto_drop => FALSE,
enabled => TRUE);
END;
用如下方式启动任务
declare
l_enqueue_options dbms_aq.enqueue_options_t
l_message_properties dbms_aq.message_properties_t
l_message_handle raw(16)
l_queue_msg event_job_test_t
begin
l_queue_msg := event_job_test_t('HR','give_me_an_event')
dbms_aq.enqueue(
queue_name=>'event_queue',
enqueue_options=>l_enqueue_options,
message_properties=>l_message_properties,
payload=>l_queue_msg,
msgid=>l_message_handle)
commit
end;
/
执行完毕后在测试表中检查结果如下
SQL> select * from event_job_test ;
ID CREATEDATE
---------- ------------------
1 14-APR-11
删除所有创建的高级队列以及相关对象
先删除基于事件的任务
SQL> exec dbms_scheduler.drop_job('event_based_job');
PL/SQL procedure successfully completed.
停止队列
SQL> exec dbms_aqadm.stop_queue(queue_name=>'event_queue');
PL/SQL procedure successfully completed.
删除队列
SQL> exec dbms_aqadm.drop_queue(queue_name=>'event_queue');
PL/SQL procedure successfully completed.
删除队列表
SQL> exec dbms_aqadm.drop_queue_table(queue_table=>'event_queue_tab');
PL/SQL procedure successfully completed.
参考至:《教你成为10g OCP》韩思捷著
本文原创,转载请注明出处、作者
如有错误,欢迎指正
邮箱:czmcj@163.com