(8)使用Events之Aapplication拋出的Events |
[君三思] 2009-8-26 |
4.2 Application拋出的Events首先要說(shuō)明,這里所說(shuō)的Application是個(gè)代詞,即可以表示ORACLE數(shù)據(jù)庫(kù)之外的應(yīng)用程序,也可以是ORACLE數(shù)據(jù)庫(kù)中的PROCEDURE等對(duì)象,總之你就將其理解成用戶自己創(chuàng)建的對(duì)象就好了。 Scheduler 能夠拋出Events讓外部應(yīng)用處理,外部的應(yīng)用也可以拋出Events讓Scheduler啟動(dòng)job處理,不過(guò)并不是任何job都能夠?qū)ν獠繎?yīng)用拋出的Events做出響應(yīng),必須在創(chuàng)建jobs時(shí)明確指定響應(yīng)的事件。那么如何指定呢?依靠下列兩個(gè)附加的參數(shù):
下面,我們就演示創(chuàng)建一個(gè)由event觸發(fā)啟動(dòng)的job,在此之前,首先需要進(jìn)行一些準(zhǔn)備工具,比如創(chuàng)建隊(duì)列,由于隊(duì)列需要基于一個(gè)隊(duì)列表,因此在創(chuàng)建隊(duì)列之前,首先要?jiǎng)?chuàng)建一個(gè)隊(duì)列表,考慮到隊(duì)列表需要依賴一個(gè)對(duì)象類型,因此在創(chuàng)建隊(duì)列表之前,先得創(chuàng)建一個(gè)type.......復(fù)雜,具體的操作步驟如下,客官可要看仔細(xì)了: SQL> create or replace type jss_type 1 as object 2 ( 3 event_type VARCHAR2( 1 0), 4 object_owner VARCHAR2( 30 ), 5 object_name VARCHAR2( 3 0) 6 ); 7 / Type created. SQL> begin 2 dbms_aqadm.create_queue_table( 3 queue_table => ¨my_queue_tbl1¨, 4 queue_payload_type => ¨JSS_TYPE1¨, 5 multiple_consumers => true); 6 end; 7 / PL/SQL procedure successfully completed. SQL> begin 2 dbms_aqadm.create_queue( 3 queue_name => ¨event_t1¨, 4 queue_table => ¨my_queue_tbl1¨); 5 end; 6 / PL/SQL procedure successfully completed.OK, 準(zhǔn)備工作完成,下面就來(lái)創(chuàng)建一個(gè)event觸發(fā)啟動(dòng)的job,創(chuàng)建腳本如下: SQL> BEGIN 2 DBMS_SCHEDULER.CREATE_JOB ( 3 job_name => ¨EVENT_JOB_T1¨, 4 job_type => ¨STORED_PROCEDURE¨, 5 job_action => ¨P_INSERTINTOTEST¨, 6 event_condition => ¨tab.user_data.event_type = ¨¨OP_INSERT¨¨¨, 7 queue_spec => ¨EVENT_T1¨, 8 enabled => TRUE); 9 END; 10 / PL/SQL procedure successfully completed.上述腳本僅做演示,因此創(chuàng)建的job仍然執(zhí)行P_INSERTINTOTEST過(guò)程。 三思并不準(zhǔn)備再編寫一套外部的應(yīng)用來(lái)觸發(fā),這里僅為了演示application觸發(fā)job啟動(dòng)的示例,因此三思決定通過(guò)pl/sql直接向event_t1隊(duì)列中添加消息的方式,觸發(fā)job的啟動(dòng),具體操作如下。 首先要執(zhí)行DBMS_AQADM.START_QUEUE過(guò)程,將event_t1置于允許入隊(duì)和出隊(duì)狀態(tài)(默認(rèn)情況下創(chuàng)建的隊(duì)列是不允許出隊(duì)和入隊(duì)操作的),腳本如下: SQL> exec dbms_aqadm.start_queue(queue_name => ¨event_t1¨,enqueue => true,dequeue => true); PL/SQL procedure successfully completed.執(zhí)行入隊(duì)操作: SQL> declare 2 v_Message jss_type1; 3 v_EnqueueOptions dbms_aq.enqueue_options_t; 4 v_MessageProperties dbms_aq.message_properties_t; 5 v_msg_handle raw(16); 6 begin 7 v_message := jss_type1(¨OP_ SELECT ¨, user, ¨tmpObj¨); 8 9 dbms_aq.enqueue(queue_name => ¨event_t1¨, 10 enqueue_options => v_enqueueOptions, 11 message_properties => v_messageproperties, 12 payload => v_message, 13 msgid => v_msg_handle); 14 commit; 15 16 end; 17 / PL/SQL procedure successfully completed.查詢隊(duì)列表中的數(shù)據(jù): SQL> select user_data from my_queue_tbl1; USER_DATA(EVENT_TYPE, OBJECT_OWNER, OBJECT_NAME) --------------------------------------------------------- JSS_TYPE1(¨OP_SELECT¨, ¨TEST¨, ¨tmpObj¨)然后查詢job SQL> select to_char(created,¨yyyy-mm-dd hh24:mi:ss¨) from jss_1; TO_CHAR(CREATED,¨YY ------------------- 2009-08-25 12:49:29看起來(lái)jss_1表中并未有新增加記錄,似乎job沒(méi)有執(zhí)行啊。這很正常,還記得咱們創(chuàng)建job時(shí)指定的 event_condition 條件嗎:
沒(méi)錯(cuò),只有當(dāng)event_type為¨OP_INSERT¨時(shí)才會(huì)觸發(fā)job的執(zhí)行,前面入隊(duì)時(shí)指定的是 OP_ SELECT ,當(dāng)然沒(méi)有觸發(fā)job中指定的procedure啦,下面再次執(zhí)行入隊(duì)操作: SQL> declare 2 v_Message jss_type1; 3 v_EnqueueOptions dbms_aq.enqueue_options_t; 4 v_MessageProperties dbms_aq.message_properties_t; 5 v_msg_handle raw(16); 6 begin 7 v_message := jss_type1(¨OP_INSERT¨, user, ¨tmpObj¨); 8 9 dbms_aq.enqueue(queue_name => ¨event_t1¨, 10 enqueue_options => v_enqueueOptions, 11 message_properties => v_messageproperties, 12 payload => v_message, 13 msgid => v_msg_handle); 14 commit; 15 16 end; 17 /再次查看jss_1表看看: SQL> select to_char(created,¨yyyy-mm-dd hh24:mi:ss¨) from jss_1; TO_CHAR(CREATED,¨YY ------------------- 2009-08-25 12:49:29 2009-08-25 13:21:21多了一條記錄,說(shuō)明job已經(jīng)被自動(dòng)觸發(fā)。 最后再補(bǔ)充一句,基于event的job不能通過(guò)DBMS_SCHEDULER.RUN_JOB過(guò)程執(zhí)行,否則會(huì)觸發(fā)ORA-00942: table or view does not exist錯(cuò)誤。 |