(8)使用Events之Aapplication拋出的Events |
[君三思] 2009-8-26 |
4.2 Application拋出的Events首先要說明,這里所說的Application是個代詞,即可以表示ORACLE數(shù)據(jù)庫之外的應(yīng)用程序,也可以是ORACLE數(shù)據(jù)庫中的PROCEDURE等對象,總之你就將其理解成用戶自己創(chuàng)建的對象就好了。 Scheduler 能夠拋出Events讓外部應(yīng)用處理,外部的應(yīng)用也可以拋出Events讓Scheduler啟動job處理,不過并不是任何job都能夠?qū)ν獠繎?yīng)用拋出的Events做出響應(yīng),必須在創(chuàng)建jobs時明確指定響應(yīng)的事件。那么如何指定呢?依靠下列兩個附加的參數(shù):
下面,我們就演示創(chuàng)建一個由event觸發(fā)啟動的job,在此之前,首先需要進行一些準(zhǔn)備工具,比如創(chuàng)建隊列,由于隊列需要基于一個隊列表,因此在創(chuàng)建隊列之前,首先要創(chuàng)建一個隊列表,考慮到隊列表需要依賴一個對象類型,因此在創(chuàng)建隊列表之前,先得創(chuàng)建一個type.......復(fù)雜,具體的操作步驟如下,客官可要看仔細了: 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)備工作完成,下面就來創(chuàng)建一個event觸發(fā)啟動的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過程。 三思并不準(zhǔn)備再編寫一套外部的應(yīng)用來觸發(fā),這里僅為了演示application觸發(fā)job啟動的示例,因此三思決定通過pl/sql直接向event_t1隊列中添加消息的方式,觸發(fā)job的啟動,具體操作如下。 首先要執(zhí)行DBMS_AQADM.START_QUEUE過程,將event_t1置于允許入隊和出隊狀態(tài)(默認情況下創(chuàng)建的隊列是不允許出隊和入隊操作的),腳本如下: SQL> exec dbms_aqadm.start_queue(queue_name => ¨event_t1¨,enqueue => true,dequeue => true); PL/SQL procedure successfully completed.執(zhí)行入隊操作: 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.查詢隊列表中的數(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看起來jss_1表中并未有新增加記錄,似乎job沒有執(zhí)行啊。這很正常,還記得咱們創(chuàng)建job時指定的 event_condition 條件嗎:
沒錯,只有當(dāng)event_type為¨OP_INSERT¨時才會觸發(fā)job的執(zhí)行,前面入隊時指定的是 OP_ SELECT ,當(dāng)然沒有觸發(fā)job中指定的procedure啦,下面再次執(zhí)行入隊操作: 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多了一條記錄,說明job已經(jīng)被自動觸發(fā)。 最后再補充一句,基于event的job不能通過DBMS_SCHEDULER.RUN_JOB過程執(zhí)行,否則會觸發(fā)ORA-00942: table or view does not exist錯誤。 |