You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断Oracle Streams AQ入队的payload/消息大小是否超过32K

Oracle Streams AQ Payload 32K 超限判断实现

背景说明

根据Oracle Streams Advanced Queuing用户指南与参考文档说明:"存储RAW类型的payload时,Oracle Streams AQ会创建带LOB列的队列表作为payload存储库。payload的最大大小由访问Oracle Streams AQ的编程接口决定:PL/SQL、Java和预编译器的限制为32K;OCI接口的限制为4G。"

核心问题

如何判断入队的payload/消息大小超过PL/SQL接口的32K限制?

初始存储过程代码

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);

  /*  当payload消息超过32K时,消息将被存储在单独的表中
  */
  
  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;
/

最终优化实现方案

通过SYS.UTL_RAW.LENGTH计算转换为RAW类型后的payload长度,和32000阈值做判断,超过阈值的大消息单独存入扩展表,AQ队列仅存储标记:

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);

  /* 当payload消息超过32K时,消息将被存储在单独的表中
  */
  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;
/

内容的提问来源于stack exchange,提问作者PurpleGreen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:36:07