【问题标题】:How do I grant CLOB privileges to a foreign queue user in Oracle Advanced Queuing?如何在 Oracle Advanced Queuing 中向外部队列用户授予 CLOB 权限?
【发布时间】:2021-03-16 16:20:09
【问题描述】:

我们将架构 A 的以下特权授予用户 B,以便在 Oracle 12c 中插入队列:

GRANT CREATE SESSION TO &UNAME_ENQUEUE;
GRANT EXECUTE ON SYS.DBMS_AQ TO &UNAME_ENQUEUE;
GRANT EXECUTE ON SYS.DBMS_AQADM TO &UNAME_ENQUEUE;
GRANT EXECUTE ON SYS.DBMS_AQIN TO &UNAME_ENQUEUE;
GRANT EXECUTE ON SYS.DBMS_AQJMS TO &UNAME_ENQUEUE;

...

    DBMS_AQADM.GRANT_QUEUE_PRIVILEGE (
            privilege        =>    'ENQUEUE',
            queue_name       =>    v_queue_name,
            grantee          =>    v_grantee_name,
            grant_option     =>    FALSE);

队列表定义为:

dbms_aqadm.create_queue_table(queue_table => 'queue_name_t', queue_payload_type => 'sys.aq$_jms_message');

...

GRANT INSERT ON &USERNAME..queue_name_t TO &UNAME_ENQUEUE;
GRANT SELECT ON &USERNAME..queue_name_t TO &UNAME_ENQUEUE;

通过 JMS 接口访问队列。我们注意到对于大小大于 x 的消息,Oracle 希望将消息负载存储为 CLOB。首先,我们不知道 x。从the Specification of the JMS message type 猜测,文本消息应该是 4000,字节消息应该是 2000,因为较小的消息适合 text_vc 或 bytes_raw。然而,有效载荷只有大约 500 个字符长。 (我们确实设置了几个标题,但如果我正确理解类型,它们会进入单独的标题“字段”)。

然而,主要问题是当用户 B 想要将 CLOB 大小的消息插入模式 A 时,我们收到错误 ORA-01031: insufficient privileges。作为用户 A 授权,问题不会出现。

  1. 我们如何向用户 B 授予必要的权限?
  2. Oracle 何时选择使用 (C)LOB?

【问题讨论】:

    标签: oracle oracle-aq


    【解决方案1】:

    1.我们如何向用户 B 授予必要的权限?

    请为ORA-01031: insufficient privileges 提供更广泛的异常堆栈,此消息并未说明根本原因 这是我的想法。

    在 Oracle DB 中,JMS 类型的排队有一个先决条件,例如 sys.aq$_jms_message 尝试为您的队列启用它。

    begin
    dbms_aqadm.enable_jms_types(queue_table => v_queue_name);
    end;
    /
    

    顺便说一句。带有 LOB 的负载需要对队列表的显式选择、插入和更新权限

    2.Oracle 什么时候选择使用 (C)LOB?

    无需从文档中猜测。您用于队列的有效负载类型将文本消息存储在 text_vc 或 text_lob 变量中。你写了the payload is only about 500 characters long,正如你所见,类型定义字段被声明为 varchar2(4000) 这并不一定意味着它是关于字符的,它也可以是关于字节的——当没有明确的声明时,它由nls 参数(另见link) select * from V$NLS_PARAMETERS t where t.PARAMETER = 'NLS_LENGTH_SEMANTICS';

    对于 aq$_jms_text_message 有 2 个选项,您可以提供大对象数据类型作为输入参数,或者您的消息 >= 4000,这就是 Oracle 将其存储为 clob 的原因。 类似的情况是 aq$_jms_bytes_message (payload IN RAW if the length of bytes_lob is =

    SYS.AQ$_JMS_MESSAGE (
      text_vc       varchar2(4000),
      text_lob      clob,
    ...
    
      -- set_text sets payload in varchar2 into text_vc if the length of
      -- payload is <= 4000, into text_lob if otherwise.
      MEMBER PROCEDURE set_text ( payload IN VARCHAR2 ),
    ..
      --
      -- set_text sets payload in clob in text_lob.
      MEMBER PROCEDURE set_text ( payload IN CLOB ),
    ...
    )
    

    顺便说一句。还有一些方法,如 DBMS_AQADM.ENABLE_DB_ACCESS 用于使用 HTTP 协议和安全队列的代理,也许值得检查一下

    【讨论】:

    • 感谢您的回答。实际上,用户缺少 UPDATE 权限,并且在插入 CLOB 或 LOB 消息时似乎是相关的。
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多