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

junsansi發表於2009-08-26

4.2 Application丟擲的Events

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

  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)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-613286/,如需轉載,請註明出處,否則將追究法律責任。

相關文章