我们如何判断payload/message的大小是否超过了32K呢?
How do we determine if the size of the payload/message exceeds 32K?
根据 Oracle 的 Streams Advanced Queuing 用户指南和参考:“为了存储 RAW 类型的负载,Oracle Streams AQ 创建了一个队列 table,其中包含 LOB 列作为负载存储库。负载的最大大小由您用于访问 Oracle Streams AQ 的编程接口决定。对于 PL/SQL、Java 和预编译器,限制为 32K;对于 OCI,限制为 4G。"
所以我的问题是我们如何确定 payload/message 的大小是否超过 32K?
现有的 Oracle 过程如下所示:
CREATE OR REPLACE procedure PRC_ordercreated(P_MSG in clob, P_MSGID out raw)
is
V_ENQUEUEOPTIONS SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
V_MESSAGEPROPERTIES SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
V_QUEUENAME varchar2(35) := 'QUE_ordercreated';
begin
V_MESSAGEPROPERTIES.USER_PROPERTY := SYS.ANYDATA.CONVERTTIMESTAMPTZ(systimestamp);
/* when the payload message exceeds 32K, the message will be stored in a separate table
*/
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW(P_MSG),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
insert into QUEUE_OVERSIZEDMESSAGE(
MSGID,
LARGEMESSAGE)
values (
P_MSGID,
P_MSG);
end;
/
[更新] 在@kfinity 的回答的帮助下,请在下面找到我的最终解决方案:
CREATE OR REPLACE procedure PRC_ENQUEUE(P_MSG in clob, P_MSGID out raw)
is
V_ENQUEUEOPTIONS SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
V_MESSAGEPROPERTIES SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
V_QUEUENAME varchar2(16) := 'QUE_ORDERCREATED';
V_MAXPAYLOADSIZE number := 32000;
begin
V_MESSAGEPROPERTIES.USER_PROPERTY := SYS.ANYDATA.CONVERTTIMESTAMPTZ(systimestamp);
/* When the payload message exceeds 32K, the message will be stored in a separate table
*/
if SYS.UTL_RAW.LENGTH(SYS.UTL_RAW.CAST_TO_RAW(P_MSG)) > V_MAXPAYLOADSIZE then
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW('IsLargeMessage'),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
insert into QUEUE_LARGEMESSAGE(
MSGID,
LARGEMESSAGE,
CREATIONDATETIME,
LASTMODIFICATIONDATETIME)
values (
P_MSGID,
P_MSG,
systimestamp,
systimestamp);
else
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW(P_MSG),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
end if;
end;
/
我会添加一个 IF 语句来检查原始变量的长度。最大大小为 32767.
CREATE OR REPLACE procedure PRC_ordercreated(P_MSG in clob, P_MSGID out raw)
is
V_ENQUEUEOPTIONS SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
V_MESSAGEPROPERTIES SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
V_QUEUENAME varchar2(35) := 'QUE_ordercreated';
begin
V_MESSAGEPROPERTIES.USER_PROPERTY := SYS.ANYDATA.CONVERTTIMESTAMPTZ(systimestamp);
/* when the payload message exceeds 32K, the message will be stored in a separate table
*/
if SYS.UTL_RAW.LENGTH(SYS.UTL_RAW.CAST_TO_RAW(P_MSG)) < 32768 then
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW(P_MSG),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
else
insert into QUEUE_OVERSIZEDMESSAGE(
MSGID,
LARGEMESSAGE)
values (
P_MSGID,
P_MSG);
end if;
end;
/
如果您仍想在负载过大时向队列中添加消息,您可能需要调整此项,也许使用占位符负载代替?
根据 Oracle 的 Streams Advanced Queuing 用户指南和参考:“为了存储 RAW 类型的负载,Oracle Streams AQ 创建了一个队列 table,其中包含 LOB 列作为负载存储库。负载的最大大小由您用于访问 Oracle Streams AQ 的编程接口决定。对于 PL/SQL、Java 和预编译器,限制为 32K;对于 OCI,限制为 4G。"
所以我的问题是我们如何确定 payload/message 的大小是否超过 32K?
现有的 Oracle 过程如下所示:
CREATE OR REPLACE procedure PRC_ordercreated(P_MSG in clob, P_MSGID out raw)
is
V_ENQUEUEOPTIONS SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
V_MESSAGEPROPERTIES SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
V_QUEUENAME varchar2(35) := 'QUE_ordercreated';
begin
V_MESSAGEPROPERTIES.USER_PROPERTY := SYS.ANYDATA.CONVERTTIMESTAMPTZ(systimestamp);
/* when the payload message exceeds 32K, the message will be stored in a separate table
*/
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW(P_MSG),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
insert into QUEUE_OVERSIZEDMESSAGE(
MSGID,
LARGEMESSAGE)
values (
P_MSGID,
P_MSG);
end;
/
[更新] 在@kfinity 的回答的帮助下,请在下面找到我的最终解决方案:
CREATE OR REPLACE procedure PRC_ENQUEUE(P_MSG in clob, P_MSGID out raw)
is
V_ENQUEUEOPTIONS SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
V_MESSAGEPROPERTIES SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
V_QUEUENAME varchar2(16) := 'QUE_ORDERCREATED';
V_MAXPAYLOADSIZE number := 32000;
begin
V_MESSAGEPROPERTIES.USER_PROPERTY := SYS.ANYDATA.CONVERTTIMESTAMPTZ(systimestamp);
/* When the payload message exceeds 32K, the message will be stored in a separate table
*/
if SYS.UTL_RAW.LENGTH(SYS.UTL_RAW.CAST_TO_RAW(P_MSG)) > V_MAXPAYLOADSIZE then
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW('IsLargeMessage'),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
insert into QUEUE_LARGEMESSAGE(
MSGID,
LARGEMESSAGE,
CREATIONDATETIME,
LASTMODIFICATIONDATETIME)
values (
P_MSGID,
P_MSG,
systimestamp,
systimestamp);
else
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW(P_MSG),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
end if;
end;
/
我会添加一个 IF 语句来检查原始变量的长度。最大大小为 32767.
CREATE OR REPLACE procedure PRC_ordercreated(P_MSG in clob, P_MSGID out raw)
is
V_ENQUEUEOPTIONS SYS.DBMS_AQ.ENQUEUE_OPTIONS_T;
V_MESSAGEPROPERTIES SYS.DBMS_AQ.MESSAGE_PROPERTIES_T;
V_QUEUENAME varchar2(35) := 'QUE_ordercreated';
begin
V_MESSAGEPROPERTIES.USER_PROPERTY := SYS.ANYDATA.CONVERTTIMESTAMPTZ(systimestamp);
/* when the payload message exceeds 32K, the message will be stored in a separate table
*/
if SYS.UTL_RAW.LENGTH(SYS.UTL_RAW.CAST_TO_RAW(P_MSG)) < 32768 then
SYS.DBMS_AQ.ENQUEUE(
QUEUE_NAME => V_QUEUENAME,
PAYLOAD => SYS.UTL_RAW.CAST_TO_RAW(P_MSG),
ENQUEUE_OPTIONS => V_ENQUEUEOPTIONS,
MESSAGE_PROPERTIES => V_MESSAGEPROPERTIES,
MSGID => P_MSGID);
else
insert into QUEUE_OVERSIZEDMESSAGE(
MSGID,
LARGEMESSAGE)
values (
P_MSGID,
P_MSG);
end if;
end;
/
如果您仍想在负载过大时向队列中添加消息,您可能需要调整此项,也许使用占位符负载代替?