Always check out the original article at http://www.oraclequirks.com for latest comments, fixes and updates.After a fortnight spent working with
DBMS_AQ and
DBMS_AQADM packages, i'd be ready to feed oraclequirks with interesting situations for days, if not weeks if only i had enough time to do so.
Unfortunately i am rather busy sorting out some important stuff before leaving or OOW 2009, so i decided to pick one of my favorite AQ (Advanced Queuing) quirks concerning bulk dequeuing of messages, via
DBMS_AQ.DEQUEUE_ARRAY in Oracle 10gR2 (XE on Xubuntu linux), as this situation may easily drive you mad.
create or replace
procedure MESSAGE_READER as
dequeue_options dbms_aq.dequeue_options_t;
msg_prop_in_array dbms_aq.message_properties_array_t;
msgid_in_array dbms_aq.msgid_array_t;
type payload_array is varray(30) of payload_type;
msg_in_array payload_array;
l_msgs_in pls_integer;
begin
msg_prop_in_array := dbms_aq.message_properties_array_t();
msg_in_array := payload_array();
msgid_in_array := dbms_aq.msgid_array_t();
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.consumer_name := 'MESSAGE_READER';
dequeue_options.wait := DBMS_AQ.NO_WAIT;
l_msgs_in := dbms_aq.dequeue_array(
queue_name => 'INBOX',
dequeue_options => dequeue_options,
array_size => 30,
message_properties_array => msg_prop_in_array,
payload_array => msg_in_array,
msgid_array => msgid_in_array);
...
end;
The most interesting property of this procedure is that it runs
without raising any errors, but simply
doesn't dequeue any messages from the queue.
So, you see you queue full of messages in
READY state, but the procedure doesn't pull out any data.
The value returned by
DBMS_AQ.DEQUEUE_ARRAY function and stored into variable
l_msgs_in remains zero and the collection remains empty, however no exceptions are raised.
While i felt that something weird must be going on behind the scenes, i did not figure out the solution until i read this
thread on OTN.
As soon as i declared the type as a stand-alone SQL type, in contrast with the PL/SQL declaration above (in red color), the procedure started working properly.
create type type payload_array as varray(30) of payload_type;
create or replace
procedure MESSAGE_READER as
dequeue_options dbms_aq.dequeue_options_t;
msg_prop_in_array dbms_aq.message_properties_array_t;
msgid_in_array dbms_aq.msgid_array_t;
msg_in_array payload_array;
l_msgs_in pls_integer;
begin
msg_prop_in_array := dbms_aq.message_properties_array_t();
msg_in_array := payload_array();
msgid_in_array := dbms_aq.msgid_array_t();
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.consumer_name := 'MESSAGE_READER';
dequeue_options.wait := DBMS_AQ.NO_WAIT;
l_msgs_in := dbms_aq.dequeue_array(
queue_name => 'INBOX',
dequeue_options => dequeue_options,
array_size => 30,
message_properties_array => msg_prop_in_array,
payload_array => msg_in_array,
msgid_array => msgid_in_array);
...
end;
Don't ask me why.
I ignore if this problem or bug, whatever we wanna call it, has been fixed in subsequent releases and/or it affects all platforms.