Oracle の Streams Advanced Queuing User's Guide and Reference によると、「タイプ RAW のペイロードを格納するために、Oracle Streams AQ は LOB 列を含むキュー テーブルをペイロード リポジトリとして作成します。ペイロードの最大サイズは、使用するプログラム インターフェイスによって決まります。 Oracle Streams AQにアクセスします。PL/SQL、Javaおよびプリコンパイラの制限は32K、OCIの制限は4Gです。」
私の質問は、ペイロード/メッセージのサイズが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;
/