Как заставить Oracle выполнять процедуру обратного вызова не SYS, а владельцем процедуры - PullRequest
1 голос
/ 24 июня 2019

Я новичок в Oracle Advanced Queuing. У меня есть процесс, который ставит в очередь, и процедуру обратного вызова, которая подписывается и регистрируется для элементов в этой очереди. Все эти объекты были созданы в пользовательской схеме. Но когда элемент появляется в очереди, процедура обратного вызова запускается, но не пользователем схемы, а пользователем SYS. Какие настройки нужно сделать, чтобы Oracle выполнял процедуру обратного вызова не пользователем SYS, а пользователем-владельцем схемы, где была создана процедура обратного вызова

Я использовал пример отсюда http://innerlife.io/ru/oracle-db-advanced-queuing-subscriber-2/

CREATE OR REPLACE TYPE tp_queue AS OBJECT (n NUMBER);

BEGIN
    DBMS_AQADM.create_queue_table ('tq_test',
                                   'tp_queue',
                                   multiple_consumers   => TRUE);
END;

BEGIN
    DBMS_AQADM.create_queue ('q_test', 'tq_test');
END;

BEGIN
    DBMS_AQADM.start_queue ('q_test');
END;

CREATE TABLE t_log
(
    d_add    TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
    s_msg    VARCHAR2 (4000)
);

CREATE OR REPLACE PACKAGE pkg_queue
IS
    PROCEDURE addLog (pi_msg IN t_log.s_msg%TYPE);

    PROCEDURE subscriber (context    RAW,
                          reginfo    SYS.AQ$_REG_INFO,
                          descr      SYS.AQ$_DESCRIPTOR,
                          payload    RAW,
                          payloadl   NUMBER);
END pkg_queue;

CREATE OR REPLACE PACKAGE BODY pkg_queue
IS
    PROCEDURE addLog (pi_msg IN t_log.s_msg%TYPE)
    AS
    BEGIN
        INSERT INTO t_log (s_msg)
             VALUES (pi_msg);
    END;

    PROCEDURE subscriber (context    RAW,
                          reginfo    SYS.AQ$_REG_INFO,
                          descr      SYS.AQ$_DESCRIPTOR,
                          payload    RAW,
                          payloadl   NUMBER)
    AS
        l_tr_obj       tp_queue;
        l_msg_props    DBMS_AQ.MESSAGE_PROPERTIES_T;
        l_queue_opts   DBMS_AQ.DEQUEUE_OPTIONS_T;
        l_msg_id       RAW (16);
    BEGIN
        l_queue_opts.consumer_name := descr.consumer_name;
        l_queue_opts.msgid := descr.msg_id;
        DBMS_AQ.dequeue (descr.queue_name,
                         l_queue_opts,
                         l_msg_props,
                         l_tr_obj,
                         l_msg_id);
        addLog (USER);
    EXCEPTION
        WHEN OTHERS
        THEN
            addLog (SQLERRM);
    END;
END pkg_queue;

BEGIN
    DBMS_AQADM.add_subscriber ('q_test',
                               sys.AQ$_AGENT ('test_subscriber', NULL, NULL));
    DBMS_AQ.register (sys.AQ$_REG_INFO_LIST (sys.AQ$_REG_INFO (
                                                 'q_test:test_subscriber',
                                                 DBMS_AQ.namespace_aq,
                                                 'plsql://pkg_queue.subscriber',
                                                 HEXTORAW ('FF'))),
                      1);
END;

DECLARE
    l_msg_props    DBMS_AQ.MESSAGE_PROPERTIES_T;
    l_queue_opts   DBMS_AQ.ENQUEUE_OPTIONS_T;
    l_msg_id       RAW (16);
BEGIN
    DBMS_AQ.enqueue ('q_test',
                     l_queue_opts,
                     l_msg_props,
                     tp_queue (1),
                     l_msg_id);
    COMMIT;
END;

Запрос из таблицы t_log возвращает «SYS». Таким образом, процедура обратного вызова была запущена пользователем SYS. Но я ожидал увидеть пользователя - владельца схемы, где эти объекты были созданы. Это не SYS. Как этого добиться?

...