二仗岖、知識補充
1、隊列:一種數(shù)據(jù)結(jié)構(gòu)览妖,就像一根管道一樣轧拄,進程一個個的塞進去,然后一個個的出來黄痪,講究的是先進先出紧帕。
2盔然、高級隊列:
a桅打、高級隊列管理是Oracle數(shù)據(jù)庫的一個特性,它提供消息隊列管理功能愈案。這是一個非惩ξ玻可靠、安全和可伸縮的消息管理系統(tǒng)站绪,因為它使用與其他基于Oracle技術(shù)的應(yīng)用程序相同的數(shù)據(jù)庫特性遭铺。
b、高級隊列管理的一個很大優(yōu)點是它可以通過PL/SQL、Java或C來訪問魂挂,這樣你就可以把來自一個Java servlet的消息入隊列和使PL/SQL存儲過程中的相同消息出隊列甫题。
c、高級隊列管理的另一個優(yōu)點是你可以利用這一軟件通過Oracle Net Services (SQL*Net)涂召、HTTP(S)和SMTP坠非,在遠(yuǎn)程節(jié)點之間傳播消息。高級隊列甚至可以通過消息網(wǎng)關(guān)與非Oracle的消息管理系
統(tǒng)(如IBM MQSeries)相集成果正。
d炎码、Oracle高級隊列管理提供了單消費者隊列和多消費者隊列。單消費者隊列只面向單一的接收者秋泳。多消費者隊列可以被多個接收者使用潦闲。當(dāng)把消息放入多消費者隊列時,應(yīng)用程序的程序員必須顯式地在消息屬性中指定這些接收者迫皱,或者建立決定每條消息的接收者的基于規(guī)則的訂閱過程歉闰。
三、基于事件的調(diào)度
創(chuàng)建測試用表
conn hr/hr
create table event_job_test(id number,createdatae date);
alter table event_job_test add constraint pk_event_job_test primary key(id);
create sequence seq_event_job_test;
創(chuàng)建一個類型:
create or replace type t_event_queueasobject(object_owner varchar2(50),event_name varchar2(50));
創(chuàng)建一個隊列表卓起,該隊列包含的字段就是我們剛才創(chuàng)建的類型t_event_queue所包含的屬性新娜。
conn /as sysdba
grant execute on dbms_aqadm to hr;
conn hr/hr
begin
dbms_aqadm.create_queue_table(
queue_table=>'event_queue_tab',
queue_payload_type=>'t_event_queue',
multiple_consumers=>true);
end;/
創(chuàng)建一個隊列,并將該隊列與前面創(chuàng)建的隊列表關(guān)聯(lián)
begin
dbms_aqadm.create_queue(
queue_name=>'event_queue',
queue_table=>'event_queue_tab');
end;/
啟動隊列
begin
dbms_aqadm.start_queue(queue_name=>'event_queue');
end;/
?創(chuàng)建一個基于事件的任務(wù)
conn /as sysdba
BEGIN
sys.dbms_scheduler.create_job(
job_name =>'"HR"."EVENT_BASE_JOB"',
job_type =>'PLSQL_BLOCK',
job_action =>'begin? insert into hr.event_job_test values(seq_event_job_test.nextval,sysdate);
? commit;
end;',event_condition =>'tab.user_data.object_owner=''HR'' andtab.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;
向隊列中插入消息
沒插入之前既绩,查詢表概龄,發(fā)現(xiàn)沒數(shù)據(jù)。
conn hr/hrselect*fromevent_job_test;
向隊列里插入消息
conn /as sysdba
grant execute on dbms_aq to hr;
conn hr/hr
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 t_event_queue;
begin
? ? l_queue_msg := t_event_queue('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;select*fromevent_job_test;
刪除作業(yè):
begin
? dbms_scheduler.drop_job(job_name =>'"HR"."EVENT_BASE_JOB"', force =>true);
end;
創(chuàng)建基于事件的調(diào)度加載數(shù)據(jù)
創(chuàng)建測試用表
conn scott/tiger
create table t asselect*fromempwhere1=2;
vi /u01/load.ctl
load data
infile '/u01/data.txt'badfile '/u01/bad.emp'discardfile '/u01/discadr.emp'truncate
into table t
fields terminated by ','trailing nullcols
(EMPNO,
ENAME,
JOB,
MGR,
HIREDATE,
SAL,
COMM,
DEPTNO)
vi /u01/load.sh
#!/bin/bash
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2/db_1
export ORACLE_SID=orcl
$ORACLE_HOME/bin/sqlldr scott/tiger control=/u01/load.ctl log=/u01/load.log
保存退出
chmod +x /u01/load.sh
將emp中的數(shù)據(jù)轉(zhuǎn)儲到/u01/data.txt中:
set trims on
spool /u01/data.txtselect
? ? EMPNO||','||? ? ENAME||','||? ? JOB||','||? ? MGR||','||? ? HIREDATE||','||? ? SAL||','||? ? COMM||','||? ? DEPTNO from emp;
spool off
創(chuàng)建一個類型:
sqlplus scott/tiger
create or replace type t_event_queue asobject(
? object_owner? ? varchar2(10),
? object_name? ? varchar2(20),
? event_type? ? ? varchar2(20),
? event_timestamp number(2)
);/
創(chuàng)建一個隊列表饲握,該隊列包含的字段就是我們剛才創(chuàng)建的類型t_event_queue所包含的屬性私杜。
conn /as sysdba
grant execute on dbms_aqadm to scott;
conn scott/tiger
begin
dbms_aqadm.create_queue_table(
queue_table=>'event_queue_tab',
queue_payload_type=>'t_event_queue',
multiple_consumers=>true);
end;/
創(chuàng)建一個隊列,并將該隊列與前面創(chuàng)建的隊列表關(guān)聯(lián)
begin
dbms_aqadm.create_queue(
queue_name=>'event_queue',
queue_table=>'event_queue_tab');
end;/
啟動隊列
begin
dbms_aqadm.start_queue(queue_name=>'event_queue');
end;/
創(chuàng)建一個基于事件的任務(wù)
conn /as sysdba
BEGIN
? sys.dbms_scheduler.create_job(job_name? ? ? ? =>'"SYS"."PERFORM_DATA_LOAD"', --屬主必須是sys
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? job_type? ? ? ? =>'EXECUTABLE',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? job_action? ? ? =>'/u01/load.sh',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? event_condition =>'tab.user_data.object_owner =? ''SCOTT''and tab.user_data.object_name =''DATA.TXT''?
and tab.user_data.event_type =''FILE_ARRIVAL''and tab.user_data.event_timestamp <9',--創(chuàng)建一個作業(yè)救欧,如果成批裝入的數(shù)據(jù)文件在上午 9:00 之前到達文件系統(tǒng)衰粹,則運行此作業(yè)queue_spec? ? ? =>'SCOTT.EVENT_QUEUE',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? start_date? ? ? => systimestamp at time zone
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? '+8:00',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? job_class? ? ? =>'DEFAULT_JOB_CLASS',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? auto_drop? ? ? => FALSE,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enabled? ? ? ? => TRUE);
END;/
向隊列中插入消息
conn scott/tigerselect*fromt;
向隊列里插入消息
conn /as sysdba
grant execute on dbms_aq to scott;
conn scott/tiger
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? ? ? ? ? t_event_queue;
begin
? l_queue_msg := t_event_queue('SCOTT','DATA.TXT','FILE_ARRIVAL',8);
? 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;/select*fromt;
刪除作業(yè):
conn /as sysdba
begin
? dbms_scheduler.drop_job(job_name =>'"SYS"."PERFORM_DATA_LOAD"', force =>true);
end;/
總結(jié)一下oracle db里用job調(diào)度shell的注意點:
1、shell腳本里開頭要加#!/bin/bash等指定使用的shell類型
2笆怠、所有相關(guān)環(huán)境變量都得在shell里明確指定
3铝耻、如果要寫入文件必需使用絕對路徑
4、使用sys用戶建立job