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

PL/SQL中创建SYS.AQ$_JMS_TEXT_MESSAGE数组批量入队报错求助

问题分析与解决

你的代码存在几个关键问题:

  • 错误使用self关键字:self只能在对象类型的成员方法中使用,直接在PL/SQL块里调用self.set_text会报错。
  • 消息类型不匹配:你定义的负载类型是sys.aq$_jms_text_message,但代码里却用了sys.aq$_jms_bytes_message.construct构造消息,类型不一致。
  • 消息对象初始化方式错误:需要先构造sys.aq$_jms_text_message实例,再调用其set_text方法设置消息内容,不能直接在对象构造时链式调用方法。

修正后的完整代码

BEGIN
  DBMS_AQADM.STOP_QUEUE (
    queue_name => 'demo_aq_array_q'
    );
  DBMS_AQADM.DROP_QUEUE (
     queue_name => 'demo_aq_array_q'
     );
  DBMS_AQADM.DROP_QUEUE_TABLE (
     queue_table => 'demo_aq_array_qt'
     );
END;
/

DROP TYPE demo_aq_array_ntt
/

DROP TYPE demo_aq_array_ot
/

CREATE OR REPLACE TYPE demo_aq_array_ot AS OBJECT
  ( id      number(10),
    message sys.aq$_jms_text_message
  );
/

CREATE TYPE demo_aq_array_ntt
AS TABLE OF demo_aq_array_ot;
/

BEGIN
  DBMS_AQADM.CREATE_QUEUE_TABLE (
     queue_table        => 'demo_aq_array_qt',
     queue_payload_type => 'demo_aq_array_ot'
     );
  DBMS_AQADM.CREATE_QUEUE (
     queue_name  => 'demo_aq_array_q',
     queue_table => 'demo_aq_array_qt'
     );
  DBMS_AQADM.START_QUEUE (
    queue_name => 'demo_aq_array_q'
    );
END;
/

set serverout on size 1000000
DECLARE

   r_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
   r_msg_properties  DBMS_AQ.MESSAGE_PROPERTIES_T;
   nt_msg_properties DBMS_AQ.MESSAGE_PROPERTIES_ARRAY_T;
   nt_payloads       demo_aq_array_ntt;
   nt_msg_ids        DBMS_AQ.MSGID_ARRAY_T;
   v_enqueued_cnt    PLS_INTEGER := 0;
   v_jms_msg         sys.aq$_jms_text_message; -- 声明JMS文本消息变量

BEGIN

   /* Initialise the collections... */
   nt_payloads := demo_aq_array_ntt();
   nt_msg_properties := DBMS_AQ.MESSAGE_PROPERTIES_ARRAY_T();
   nt_msg_ids := DBMS_AQ.MSGID_ARRAY_T();

   /* Load up 2500 arbitrary messages... */
   FOR i IN 1 .. 2500 LOOP

      nt_payloads.EXTEND;
      -- 构造JMS文本消息实例
      v_jms_msg := sys.aq$_jms_text_message.construct;
      -- 设置消息文本内容
      v_jms_msg.set_text('Message number ' || TO_CHAR(i));
      -- 赋值给嵌套表元素
      nt_payloads(nt_payloads.LAST) := demo_aq_array_ot(i, v_jms_msg);

      nt_msg_properties.EXTEND;
      nt_msg_properties(nt_msg_properties.LAST) := r_msg_properties;

   END LOOP;

   /* Enqueue the messages in a single transaction... */
   v_enqueued_cnt := DBMS_AQ.ENQUEUE_ARRAY(
                        queue_name               => 'demo_aq_array_q',
                        enqueue_options          => r_enqueue_options,
                        array_size               => nt_payloads.COUNT,
                        message_properties_array => nt_msg_properties,
                        payload_array            => nt_payloads,
                        msgid_array              => nt_msg_ids
                        );
   COMMIT;

   DBMS_OUTPUT.PUT_LINE(
      'Enqueued [' || TO_CHAR(v_enqueued_cnt) || '] messages.'
      );

   DBMS_OUTPUT.PUT_LINE(
      'Received [' || TO_CHAR(nt_msg_ids.COUNT) || '] message IDs.'
      );

END;
/

关键修正点说明

  • 新增v_jms_msg变量专门用于构造和初始化JMS文本消息,避免直接在对象构造时调用方法的错误。
  • 使用sys.aq$_jms_text_message.construct构造正确类型的消息实例,与负载类型匹配。
  • 先调用set_text设置消息内容,再将消息对象赋值给自定义对象类型的属性,解决self使用错误的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:15:17