全面學習ORACLE Scheduler特性(8)使用Events之Application丟擲的Events

junsansi發表於2009-08-26

4.2 Application丟擲的Events

  首先要說明,這裡所說的Application是個代詞,即可以表示ORACLE資料庫之外的應用程式,也可以是ORACLE資料庫中的PROCEDURE等物件,總之你就將其理解成使用者自己建立的物件就好了。

[@more@]

  Scheduler 能夠丟擲Events讓外部應用處理,外部的應用也可以丟擲Events讓Scheduler啟動job處理,不過並不是任何job都能夠對外部應用丟擲的Events做出響應,必須在建立jobs時明確指定響應的事件。那麼如何指定呢?依靠下列兩個附加的引數:

  • queue_spec :指定外部應用丟擲的events訊息入隊的佇列名;
  • event_condition :指定觸發job啟動的條件,這一引數的引數值在設定時應當基於事件訊息的自身屬性,因為事件訊息在入隊時,訊息的屬性都是由application定義的,因此在設定觸發條件時,也應該根據這些屬性值就行設定。

  下面,我們就演示建立一個由event觸發啟動的job,在此之前,首先需要進行一些準備工具,比如建立佇列,由於佇列需要基於一個佇列表,因此在建立佇列之前,首先要建立一個佇列表,考慮到佇列表需要依賴一個物件型別,因此在建立佇列表之前,先得建立一個type.......複雜,具體的操作步驟如下,客官可要看仔細了:

    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, 準備工作完成,下面就來建立一個event觸發啟動的job,建立指令碼如下:

    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.

  上述指令碼僅做演示,因此建立的job仍然執行P_INSERTINTOTEST過程。

  三思並不準備再編寫一套外部的應用來觸發,這裡僅為了演示application觸發job啟動的示例,因此三思決定通過pl/sql直接向event_t1佇列中新增訊息的方式,觸發job的啟動,具體操作如下。

  首先要執行DBMS_AQADM.START_QUEUE過程,將event_t1置於允許入隊和出隊狀態(預設情況下建立的佇列是不允許出隊和入隊操作的),指令碼如下:

    SQL> exec dbms_aqadm.start_queue(queue_name => 'event_t1',enqueue => true,dequeue => true);

    PL/SQL procedure successfully completed.

  執行入隊操作:

    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.

  查詢佇列表中的資料:

    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沒有執行啊。這很正常,還記得我們們建立job時指定的 event_condition 條件嗎:

    6 event_condition => 'tab.user_data.event_type = ''OP_INSERT''',

  沒錯,只有當event_type為'OP_INSERT'時才會觸發job的執行,前面入隊時指定的是 OP_ SELECT ,當然沒有觸發job中指定的procedure啦,下面再次執行入隊操作:

    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已經被自動觸發。

  最後再補充一句,基於event的job不能通過DBMS_SCHEDULER.RUN_JOB過程執行,否則會觸發ORA-00942: table or view does not exist錯誤。

==============================================

全面學習ORACLE Scheduler特性(7)使用Events之Scheduler丟擲的Events

全面學習ORACLE Scheduler特性(6)設定Repeat Interval引數

全面學習ORACLE Scheduler特性(5)Schedules排程Programs執行的Jobs

全面學習ORACLE Scheduler特性(4)建立和管理Schedule

全面學習ORACLE Scheduler特性(3)使用Programs

全面學習ORACLE Scheduler特性(2)管理jobs

全面學習ORACLE Scheduler特性(1)建立jobs

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7607759/viewspace-1026354/,如需轉載,請註明出處,否則將追究法律責任。

相關文章