oracle - 如何在 Oracle Advanced Queuing 中向外部队列用户授予 CLOB 权限?
问题描述
我们将模式 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。根据 JMS 消息类型的规范猜测,文本消息应该是 4000,字节消息应该是 2000,因为较小的消息可以放入text_vc
or bytes_raw
。然而,有效载荷只有大约 500 个字符长。(我们确实设置了几个标题,但如果我正确理解类型,它们会进入单独的标题“字段”)。
然而,主要问题是ORA-01031: insufficient privileges
当用户 B 想要将 CLOB 大小的消息插入模式 A 时,我们会遇到错误。作为用户 A 授权,问题不会出现。
- 我们如何将必要的权限授予用户 B?
- Oracle 何时选择使用 (C)LOB?
解决方案
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 参数确定(另见链接)
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 如果 bytes_lob 的长度 =< 32767 vs payload IN BLOB )
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 协议和安全队列的代理,也许值得检查一下
推荐阅读
- excel - 通过 VBA 加载新数据文件后的动态公式调整
- go - 全局变量地址
- javascript - 检查 webElement 是否不包含文本,在 Cypress 中不区分大小写
- python - Bokeh - 为 Networkx Graph 添加边缘标签/边缘属性
- haskell - 如何使用光泽加速渲染 mandelbrot
- firebase - 如何使用 Firestore 在 Flutter 中搜索文本
- c# - 在我的字符串列表中使用 Contains() 和 Add() 方法,但它没有运行
- laravel - 当我注销并想再次登录时,Laravel SPA 返回 419
- javascript - 如何在 Flutter Web 上调用 JavaScript 事件方法
- docusignapi - 最小设计示例