053-250

You want to schedule a job to rebuild all indexes on the SALES table after the completion of a bulk load operation.
The bulk load operation must also be a scheduled job that executes as soon as the first file that contains data arrives on the system.
How would you create these jobs?
A. Create both jobs by using events raised by the scheduler
B. Create both jobs by using events raised by the application
C. Create a job to rebuild indexes by using events arised by the application and then create another job to perform bulk load by using events raised by the scheduler
D. Create a job to rebuild indexes by using events arised by the Scheduller and then create another job to perform bulk load by using events raised by the application

  本题的考点是通过事件来启动作业。其中加载数据的事务需要当文件到系统的时候触发。数据加载的作业通过监控文件到达触发,并且在完成这个作业后,再完成重建索引的作业,那么就需要创建作业连进行调度。
D 正确

一个事件的消息可以由一个应用程序或系统进程发出,被一个或多个应用程序或进程接受(消耗)。
有两种通过调度消耗事件的方式:
1.由应用程序引发事件
调度对事件作出反应,然后启动作业。应用程序需要在 ORACLE 高级队列中入队信息,并且在配置作业的时候指定使用的队列名称(基础作业的 queue_spec 属性),当作业启动时,会从事件中获得文本信息。
event_condition 属性也必须在基础作业中设置。这个是一个基于消息熟悉的条件表达式,评估消息必须满足为 true 时才会启动作业。使用的是高级队列语法。 用户属性使用 tab.user_data.的前缀。例如:
event_condition = 'tab.user_data.event_type = ''LOW_INVENTORY'' and
extract hour from tab.user_data.event_timestamp < 9'
只有在每天 9 点之前的 LOW INVENTORY 的事件才会触发。
创建一个基本事件 job:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'process_lowinv_j1',
program_name => 'process_lowinv_p1',
event_condition => 'tab.user_data.event_type = ''LOW_INVENTORY''',
queue_spec => 'inv_events_q, inv_agent1',
enabled => TRUE,
comments => 'Start an inventory replenishment job');
END;
/
指定事件调度中的事件信息:
其实就是设置作业的 schedule_name 熟悉:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'process_lowinv_j1',
program_name => 'process_lowinv_p1',
schedule_name => 'inventory_events_schedule',
enabled => TRUE,
comments => 'Start an inventory replenishment job');
END;
/

修改熟悉使用 DBMS_SCHEDULER.SET_ATTRIBUTE
例如:
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE ('my_job', 'event_spec',
'tab.user_data.event_type = ''LOW_INVENTORY''', 'inv_events_q, inv_agent1');
END;
/
创建一个事件调度:
BEGIN
DBMS_SCHEDULER.CREATE_EVENT_SCHEDULE (
schedule_name => 'inventory_events_schedule',
start_date => SYSTIMESTAMP,
event_condition => 'tab.user_data.event_type = ''LOW_INVENTORY''',
queue_spec => 'inv_events_q, inv_agent1');
END;
/
在应用程序上将事件消息传递给基于事件的作业:
这个作业的程序名称必须是 STORED_PROCEDURE, 启动的 metadata_attribute 必须是EVENT_MESSAGE。实现这个的程序必须有一个队列参数,于对象的元数据参数对应。例如:
create or replace procedure my_stored_proc (event_msg IN event_queue_type)
as
begin
-- retrieve and process message body
end;
/
begin
dbms_scheduler.create_program (
program_name => 'my_prog',
program_action=> 'my_stored_proc',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 1,
enabled => FALSE) ;
dbms_scheduler.define_metadata_argument (
program_name => 'my_prog',
argument_position => 1 ,
metadata_attribute => 'EVENT_MESSAGE') ;
dbms_scheduler.enable ('my_prog');
exception
when others then raise ;
end ;
/
begin
dbms_scheduler.create_job (
job_name => 'my_evt_job' ,
program_name => 'my_prog',
schedule_name => 'my_evt_sch',
enabled => true,
auto_Drop => false) ;
exception
when others then raise ;
end ;
/
2.通过文件观察着引发的文件到达事件
使用调度创建一个文件观察着。当文件观察着发现文件存在时,启动作业。
文件观察着检查文件是每 10 分钟一次。这个时间间隔是可以调整的。例如 2 分钟一次:
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE('FILE_WATCHER_SCHEDULE', 'REPEAT_INTERVAL',
'FREQ=MINUTELY;INTERVAL=2');
END;
/
首先创建一个凭证,也就是操作系统访问到文件的权限:
BEGIN

DBMS_SCHEDULER.CREATE_CREDENTIAL('WATCH_CREDENTIAL', 'salesapps', 'sa324w1');
END;
/
然后将下列权限赋予给文件观察者启动的用户:
GRANT EXECUTE ON WATCH_CREDENTIAL to DSSUSER;
创建文件观察着:
BEGIN
DBMS_SCHEDULER.CREATE_FILE_WATCHER(
FILE_WATCHER_NAME => 'EOD_FILE_WATCHER',
DIRECTORY_PATH => '?/eod_reports',
FILE_NAME => 'eod*.txt',
CREDENTIAL_NAME => 'WATCH_CREDENTIAL',
DESTINATION => NULL,
ENABLED => FALSE);
END;
/
?表示的是 ORACLE_HOME 路径,
给与权限:
GRANT EXECUTE ON EOD_FILE_WATCHER to DSSUSER;
创建程序:
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(
PROGRAM_NAME => 'DSSUSER.EOD_PROGRAM',
PROGRAM_TYPE => 'STORED_PROCEDURE',
PROGRAM_ACTION => 'EOD_PROCESSOR',
NUMBER_OF_ARGUMENTS => 1,
ENABLED => FALSE);
END;
/
定义 event_message 属性:
BEGIN
DBMS_SCHEDULER.DEFINE_METADATA_ARGUMENT(
PROGRAM_NAME => 'DSSUSER.EOD_PROGRAM',
METADATA_ATTRIBUTE => 'event_message',
ARGUMENT_POSITION => 1);
END;
/
创建基于事件的作业并运行:
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
JOB_NAME => 'DSSUSER.EOD_JOB',
PROGRAM_NAME => 'DSSUSER.EOD_PROGRAM',
EVENT_CONDITION => NULL,
QUEUE_SPEC => 'EOD_FILE_WATCHER',
AUTO_DROP => FALSE,
ENABLED => FALSE);
END;
/
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE('DSSUSER.EOD_JOB','PARALLEL_INSTANCES',TRUE);
END;
/



posted @ 2017-11-16 14:34  巴啦啦大魔王  阅读(110)  评论(0编辑  收藏  举报