2009-07-03 12 views
0

メッセージがキューに入れられたときにトリガーするキューとコールバックを作成しようとしていますが、トリガーするコールバックを取得できません。私は間違って何をしていますか?PL/SQLでキュー・サブスクライバを作成する構文は何ですか?

私はメッセージをエンキューするトリガーを持っており、キューメッセージテーブルでそれを見ることができます。手でデキューして処理することができます。エンキュー時にコールバックを取得できません。一見

BEGIN  
DBMS_AQADM.CREATE_QUEUE_TABLE (
    queue_table  => 'queue_message_table', 
    queue_payload_type => 'queue_message_type', 
    multiple_consumers => TRUE); 

DBMS_AQADM.CREATE_QUEUE (
    queue_name => 'message_queue', 
    queue_table => 'queue_message_table'); 
DBMS_AQADM.START_QUEUE (queue_name => 'message_queue'); 
END; 

CREATE OR REPLACE PROCEDURE queue_callback(
    context RAW, reginfo SYS.AQ$_REG_INFO, descr SYS.AQ$_DESCRIPTOR, payload RAW, payloadl NUMBER) AS 

    queue_options  DBMS_AQ.DEQUEUE_OPTIONS_T; 
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; 
    my_message   queue_message_type; 
    ret     varchar2(200); 
    message_id   RAW(16); 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Callback'); 
    queue_options.msgid := descr.msg_id; 
    queue_options.consumer_name := descr.consumer_name; 

    DBMS_AQ.DEQUEUE(
     queue_name => descr.queue_name, 
     dequeue_options => queue_options, 
     message_properties => message_properties, 
     payload => my_message, 
     msgid => message_id); 
    ret := handle_message(my_message); 
    commit; 
END; 

BEGIN 
    DBMS_AQADM.ADD_SUBSCRIBER (queue_name => 'message_queue', 
    subscriber => SYS.AQ$_AGENT('queue_subscriber', 'message_queue',NULL)); 
    DBMS_AQ.REGISTER (
    SYS.AQ$_REG_INFO_LIST(
     SYS.AQ$_REG_INFO(
     'MESSAGE_QUEUE:QUEUE_SUBSCRIBER', 
     DBMS_AQ.NAMESPACE_AQ, 
     'plsql://QUEUE_CALLBACK', 
     HEXTORAW('FF') 
    ) 
    ), 1 
); 
END; 
+0

これを修正しましたか?私は同じ問題を抱えています:http://stackoverflow.com/questions/30502535/oracle-advance-queue-dequeue-not-working – SaintLike

答えて

1

、あなたがどちらも(dbms_aqadm.start_queue)キューを開始している表示されない、どちらもあなたはそれに(dbms_aq.enqueueを)何もエンキューされています。

これに続くことをお勧めします。demo

+0

キューにメッセージを作っているのは間違いなく、私はそれらを見ることができます。コールバック作成構文で何か問題があります。 –

+0

AQ APIの呼び出しでqueue_callbackへの参照がないことがわかりました。 –

+0

AQ.REGISTER呼び出しにはREG_INFOコンストラクタの参照があります。それはオンラインデモがどうやっているかのようですが、明らかに私は何かが欠けています。コールバックへの参照がどこにあるのか知っていますか? –

1

データベースのバージョンには注意が必要です。 issues with Oracle Aqについていくつかのバグが報告されています。 特に私はthis linkのサンプルを作成し、Oracle 11gR2エンタープライズデータベースでデモを実行しました。エンキュー、デキュー、キューのパージを行っていましたが、Dbms_Aq.Registerで作成したリスナーは機能しませんでした。 Oracle 11g R2 xeデータベースをダウンロードする同じ例を実行しました。

同じ例がOracle 10gR2インスタンスで実行され、完全に機能します。

  • がDBMS_AQ.REGISTERでリスナーを登録し、適切な名前空間を使用して加入者を追加し、適切なパラメータを使用し
  • 使用:

    あなたが使用してAQに注意する必要がありますいくつかのものがあります。

  • パッケージの適切なアクセス許可を使用して、キューを処理する
  • キューの修飾名を使用するそれがうまくいかない場合は、いくつかのケースで。

「 まず

connect/as sysdba 
-- @?/rdbms/admin/dbmsaqad.sql --(install if you don't have aq installed yet) 

-- create the user and permissions 
create user aqadmin identified by aqadmin default tablespace users temporary tablespace temp; 
GRANT create session TO aqadmin; 
grant connect, resource to aqadmin; 
GRANT aq_administrator_role TO aqadmin IDENTIFIED BY aqadmin; 
GRANT execute ON dbms_aq TO aqadmin; 
GRANT execute ON dbms_aqadm TO aqadmin; 

スキーマを作成するDDLを作成

CREATE TABLE demo_queue_message_table 
(message VARCHAR2(4000)); 

create or replace type demo_queue_payload_type as object(message varchar2(4000)) ; 
/

begin 
    DBMS_AQADM.CREATE_QUEUE_TABLE (queue_table => 'demo_queue_table', queue_payload_type => 'demo_queue_payload_type',multiple_consumers => TRUE); 
    DBMS_AQADM.CREATE_QUEUE (queue_name => 'demo_queue', queue_table => 'demo_queue_table'); 
    DBMS_AQADM.START_QUEUE('demo_queue'); 
end; 
/

CREATE or replace PROCEDURE demo_queue_callback_procedure(
       context RAW, 
       reginfo SYS.AQ$_REG_INFO, 
       descr SYS.AQ$_DESCRIPTOR, 
       payload RAW, 
       payloadl NUMBER 
       ) AS 

    r_dequeue_options DBMS_AQ.DEQUEUE_OPTIONS_T; 
    r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; 
    v_message_handle  RAW(16); 
    o_payload   demo_queue_payload_type; 

BEGIN 

    r_dequeue_options.msgid := descr.msg_id; 
    r_dequeue_options.consumer_name := descr.consumer_name; 

    DBMS_AQ.DEQUEUE(
     queue_name   => descr.queue_name, 
     dequeue_options => r_dequeue_options, 
     message_properties => r_message_properties, 
     payload   => o_payload, 
     msgid    => v_message_handle 
    ); 

    INSERT INTO demo_queue_message_table (message) 
    VALUES ('Message [' || o_payload.message || '] ' || 
      'dequeued at [' || TO_CHAR(SYSTIMESTAMP, 
             'DD-MON-YYYY HH24:MI:SS.FF3') || ']'); 
    COMMIT; 

END; 
/


BEGIN 

    DBMS_AQADM.ADD_SUBSCRIBER (
     queue_name => 'demo_queue', 
     subscriber => SYS.AQ$_AGENT(
         'demo_queue_subscriber', 
         NULL, 
         NULL) 
    ); 

    DBMS_AQ.REGISTER (
     SYS.AQ$_REG_INFO_LIST(
      SYS.AQ$_REG_INFO(
      'DEMO_QUEUE:DEMO_QUEUE_SUBSCRIBER', 
      DBMS_AQ.NAMESPACE_AQ, 
      'plsql://DEMO_QUEUE_CALLBACK_PROCEDURE', 
      HEXTORAW('FF') 
      ) 
     ), 
     1 
     ); 
END; 
/

AQ-オブジェクトを作成し、最後にキュー

をテストオブジェクト
DECLARE 

    r_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T; 
    r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; 
    v_message_handle  RAW(16); 
    o_payload   demo_queue_payload_type; 

BEGIN 

    o_payload := demo_queue_payload_type(
        TO_CHAR(SYSTIMESTAMP, 'DD-MON-YYYY HH24:MI:SS.FF3') 
        ); 

    DBMS_AQ.ENQUEUE(
     queue_name   => 'demo_queue', 
     enqueue_options => r_enqueue_options, 
     message_properties => r_message_properties, 
     payload   => o_payload, 
     msgid    => v_message_handle 
    ); 

    COMMIT; 

END; 
/
関連する問題