I have a schema that owns some queues and an application that connects to that schema and uses the queues. For security reasons I want to create a user schema that can access the queue and I want the application to use the user schema from now on.
I gave queue privileges to the user like this:
BEGIN
FOR Q IN (SELECT * FROM ALL_QUEUES WHERE owner = 'OWNER_SCHEMA')
LOOP
DBMS_AQADM.GRANT_QUEUE_PRIVILEGE('ALL', 'OWNER_SCHEMA.' || Q.NAME, 'USER_SCHEMA', FALSE);
END LOOP;
END;
The problem is that the application fails cause it tries to access a queue owned by the user schema, which does not exist.
I tried to manually enqueue a message using the USER schema:
DECLARE
msg SYS.AQ$_JMS_TEXT_MESSAGE;
queue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
msg_props DBMS_AQ.MESSAGE_PROPERTIES_T;
msg_id RAW(16);
BEGIN
msg := SYS.AQ$_JMS_TEXT_MESSAGE.CONSTRUCT();
msg.set_text('
{
"someKey": "someValue"
}
');
DBMS_AQ.ENQUEUE( queue_name => 'SOME_QUEUE'
, enqueue_options => queue_options
, message_properties => msg_props
, payload => msg
, msgid => msg_id);
COMMIT;
END;
and it failed with the following error:
ORA-24010: QUEUE USER_SCHEMA.SOME_QUEUE does not exist
ORA-06512: at "SYS.DBMS_AQ", line 185
ORA-06512: at line 18
but when I try to enqueue the message using also the USER schema but reference the queue from the OWNER schema it worked (queue_name => 'SCHEMA_OWNER.SOME_QUEUE'). This worked:
DECLARE
msg SYS.AQ$_JMS_TEXT_MESSAGE;
queue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
msg_props DBMS_AQ.MESSAGE_PROPERTIES_T;
msg_id RAW(16);
BEGIN
msg := SYS.AQ$_JMS_TEXT_MESSAGE.CONSTRUCT();
msg.set_text('
{
"someKey": "someValue"
}
');
DBMS_AQ.ENQUEUE( queue_name => 'SCHEMA_OWNER.SOME_QUEUE'
, enqueue_options => queue_options
, message_properties => msg_props
, payload => msg
, msgid => msg_id);
COMMIT;
END;
I tried to create a synonym for the queue but get the same result.
The only thing that makes the application work is adding one more config property that is the schema owner so that the app can use the schema user to connect, but then use the schema owner to reference the queue, but this is not the desired solution, cause there are a lot of envs and the config file for all envs would need to be changed.
Is there a way to reference the queue directly with the USER schema?
Related
According to Oracle's Streams Advanced Queuing User's Guide and Reference: "To store a payload of type RAW, Oracle Streams AQ creates a queue table with LOB column as the payload repository. The maximum size of the payload is determined by which programmatic interface you use to access Oracle Streams AQ. For PL/SQL, Java and precompilers the limit is 32K; for the OCI the limit is 4G."
So my question is how can we determine if the size of the payload/message exceeds 32K?
The existing Oracle procedure looks like this:
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;
/
[UPDATE] With the help of #kfinity's answer, please find my final solution below:
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;
/
I would add an IF statement to check the length of the raw variable. The max size is 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;
/
You might need to adjust this if you want to still want to add a message to the queue when the payload is too large, maybe with a placeholder payload instead?
I'm checking Go ability to migrate an existing C++ application.
One of the main task is to listen actively (no polling) an Advanced Oracle Queue.
In Java and C++ there are existing libraries supporting it since a long time.
I could not find anything similar in Go (libraries & examples).
Could you help me with that?
I have an implementation whereby I'm using the "gopkg.in/goracle.v2" package to connect to Oracle, along with the generic Go library "database/sql".
The way I did it, I have the code to read from the AQ in a PL/SQL procedure which I'm calling from my Go code. Although this is not the best approach - and I'm actually going to change it so that it doesn't rely on a stored oracle procedure - it works. The code looks something like the following:
Oracle PL/SQL proc:
PROCEDURE GetAQMessage ( out_content OUT VARCHAR2, in_acknowledge IN VARCHAR2 DEFAULT 'N' )
IS
dyn_sql VARCHAR2(32000);
l_content VARCHAR2(4000);
BEGIN
dyn_sql := '
DECLARE
l_payload MESSAGE_TYPE := MESSAGE_TYPE (NULL);
l_msg_id RAW(16);
l_dequeue_options DBMS_AQ.DEQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
BEGIN
DBMS_AQ.DEQUEUE(
queue_name => '''|| v_queue_name ||''',
dequeue_options => l_dequeue_options,
message_properties => l_message_properties,
payload => l_payload,
msgid => l_msg_id
);
:b_output := l_payload.message;
END;';
EXECUTE IMMEDIATE dyn_sql USING OUT l_content;
-- Return the content to the OUT parameter
out_content := l_content;
-- Permanently removes the message from the Queue
IF in_acknowledge = 'Y' THEN
COMMIT;
END IF;
END GetAQMessage;
Go code:
func GetAQMessage(transaction *sql.Tx) (string, error) {
var outResult string
var resErr error
var debug int
configuration = conf.Read()
//Run the command
_, resErr = transaction.Exec(`BEGIN CONSENT.GETAQMESSAGE(:1,:2) ; END;`, sql.Out{Dest: &outResult}, "N")
return outResult, resErr
}
I can't seem to find the solution to my problem, I've been stuck at this for hours.
I'm usings Oracle AQs:
Dbms_Aqadm.Create_Queue_Table(Queue_Table => 'ITEM_EVENT_QT',
Queue_Payload_Type => 'ITEM_EVENT',
Multiple_Consumers => TRUE);
Dbms_Aqadm.Create_Queue(Queue_Name => 'ITEM_EVENT_QUEUE',
Queue_Table => 'ITEM_EVENT_QT',
Max_Retries => 5,
Retry_Delay => 0,
Retention_Time => 432000, -- 5 DAYS
Dependency_Tracking => FALSE,
COMMENT => 'Item Event Queue');
-- START THE QUEUE
Dbms_Aqadm.Start_Queue('ITEM_EVENT_QUEUE');
-- GRANT QUEUE PRIVILEGES
Dbms_Aqadm.Grant_Queue_Privilege(Privilege => 'ALL',
Queue_Name => 'ITEM_EVENT_QUEUE',
Grantee => 'PUBLIC',
Grant_Option => FALSE);
END;
Here's one of my subscribers:
Dbms_Aqadm.Add_Subscriber(Queue_Name => 'ITEM_EVENT_QUEUE',
Subscriber => Sys.Aq$_Agent('ITEM_SUBSCRIBER_1',
NULL,
NULL),
rule => 'tab.user_data.header.thread_no = 1');
Dbms_Aq.Register(Sys.Aq$_Reg_Info_List(Sys.Aq$_Reg_Info('ITEM_EVENT_QUEUE:ITEM_SUBSCRIBER_1',
Dbms_Aq.Namespace_Aq,
'plsql://ITEM_API.GET_QUEUE_FROM_QUEUE',
HEXTORAW('FF'))),1);
The subscriber registration:
Whenever a certain event occurs on my DB, I'm using a trigger to add "the event" to my AQ by calling the following procedure from my ITEM_API package:
PROCEDURE ADD_EVENT_TO_QUEUE(I_EVENT IN ITEM_EVENT,
O_STATUS_CODE OUT VARCHAR2,
O_ERROR_MSG OUT VARCHAR2) IS
ENQUEUE_OPTIONS DBMS_AQ.ENQUEUE_OPTIONS_T;
MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
MESSAGE_HANDLE RAW(16);
EVENT ITEM_EVENT;
HEADER_PROP HEADER_PROPERTIES;
BEGIN
EVENT := I_EVENT;
EVENT.SEQ_NO := ITEM_EVENT_SEQ.NEXTVAL;
ENQUEUE_OPTIONS.VISIBILITY := DBMS_AQ.ON_COMMIT;
ENQUEUE_OPTIONS.SEQUENCE_DEVIATION := NULL;
MESSAGE_PROPERTIES.PRIORITY := 1;
MESSAGE_PROPERTIES.DELAY := DBMS_AQ.NO_DELAY;
MESSAGE_PROPERTIES.EXPIRATION := DBMS_AQ.NEVER;
HEADER_PROP := HEADER_PROPERTIES(1);
EVENT.HEADER := HEADER_PROP;
DBMS_AQ.ENQUEUE(QUEUE_NAME => 'ITEM_EVENT_QUEUE',
ENQUEUE_OPTIONS => ENQUEUE_OPTIONS,
MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
PAYLOAD => EVENT,
MSGID => MESSAGE_HANDLE);
EXCEPTION
WHEN OTHERS THEN
ERROR_HANDLER.LOG_ERROR(NULL,
EVENT.ITEM,
EVENT.SEQ_NO,
SQLCODE,
SQLERRM,
O_STATUS_CODE,
O_ERROR_MSG);
RAISE;
END ADD_EVENT_TO_QUEUE;
And it's working because when I check my AQ table, I can find "the event", however my dequeue method is not dequeing, as you can see in the image bellow, there's no DEQ_TIME.
Here's my dequeue method, also from my ITEM_API package:
PROCEDURE GET_QUEUE_FROM_QUEUE(CONTEXT RAW,
REGINFO SYS.AQ$_REG_INFO,
DESCR SYS.AQ$_DESCRIPTOR,
PAYLOAD RAW,
PAYLOADL NUMBER) IS
R_DEQUEUE_OPTIONS DBMS_AQ.DEQUEUE_OPTIONS_T;
R_MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
V_MESSAGE_HANDLE RAW(16);
I_PAYLOAD ITEM_EVENT;
L_PROC_EVENT BOOLEAN;
O_TARGETS CFG_EVENT_STAGE_TBL;
O_ERROR_MSG VARCHAR2(300);
O_STATUS_CODE VARCHAR2(100);
BEGIN
R_DEQUEUE_OPTIONS.MSGID := DESCR.MSG_ID;
R_DEQUEUE_OPTIONS.CONSUMER_NAME := DESCR.CONSUMER_NAME;
R_DEQUEUE_OPTIONS.DEQUEUE_MODE := DBMS_AQ.REMOVE;
--R_DEQUEUE_OPTIONS.WAIT := DBMS_AQ.NO_WAIT;
DBMS_AQ.DEQUEUE(QUEUE_NAME => DESCR.QUEUE_NAME,
DEQUEUE_OPTIONS => R_DEQUEUE_OPTIONS,
MESSAGE_PROPERTIES => R_MESSAGE_PROPERTIES,
PAYLOAD => I_PAYLOAD,
MSGID => V_MESSAGE_HANDLE);
IF I_PAYLOAD IS NOT NULL THEN
L_PROC_EVENT := PROCESS_EVENT(I_PAYLOAD,
O_TARGETS,
O_STATUS_CODE,
O_ERROR_MSG);
END IF;
EXCEPTION
WHEN OTHERS THEN
ERROR_HANDLER.LOG_ERROR(NULL,
NULL,
NULL,
SQLCODE,
SQLERRM,
O_STATUS_CODE,
O_ERROR_MSG);
RAISE;
END GET_QUEUE_FROM_QUEUE;
Am I doing something wrong? How can I fix this? I think there might be a problem with my subscriber registration, but I'm not sure.
EDIT: I've just figured out that if I remove the subscribers and the register, and then re-add them, they'll dequeue all messages. Howerver if another event gets enqueued, it stays there indefinetly (or until I remove and add the subscribers again):
The record with state 0 and no DEQ_TIME is the new one.
Do I need a scheduler or something like that?
EDIT: I've added a scheduler propagation to my AQ:
DBMS_AQADM.SCHEDULE_PROPAGATION('ITEM_EVENT_QUEUE');
and even added the next_time field:
DBMS_AQADM.SCHEDULE_PROPAGATION('ITEM_EVENT_QUEUE', SYSDATE + 30/86400);
Still doesn't work. Any suggestions? I guess the AQ Notifications aren't working, and my callback procedure is never called. How can I fix this?
EDIT: I've removed my procedure from the package just for testing purposes, so my team mates can compile the ITEM_API package (I don't know if recompiling the package, may or may not have impacts on the dequeue process).
Still doesn't work.
Create a code block and run the following:
DECLARE
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW (16);
I_PAYLOAD ITEM_EVENT;
no_messages exception;
msg_content VARCHAR2 (4000);
PRAGMA EXCEPTION_INIT (no_messages, -25228);
BEGIN
dequeue_options.wait := DBMS_AQ.NO_WAIT;
dequeue_options.consumer_name := 'ITEM_SUBSCRIBER_1';
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
LOOP
DBMS_AQ.DEQUEUE (queue_name => 'ITEM_EVENT_QUEUE',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => I_PAYLOAD,
msgid => message_handle
);
END LOOP;
EXCEPTION
WHEN no_messages
THEN
DBMS_OUTPUT.PUT_LINE ('No more messages left');
END;
Let me know what happens to your enqueued messages.
You should have a table where you're dequing the data.
Can you also try adding the enqueud table in the agent and then specify the agent to the dequeue table.
DECLARE
aSubscriber sys.aq$_agent;
BEGIN
aSubscriber := sys.aq$_agent('ITEM_SUBSCRIBER_1',
'ITEM_EVENT_QUEUE',
0);
dbms_aqadm.add_subscriber
( queue_name => 'ITEM_EVENT_QUEUE'
,subscriber => aSubscriber);
END;
/
We faced a related problem (at least related to the title), we couldn't dequeue messages with a delay. The messages in the queue stayed the state "WAITING". And were not changed to "READY".
The Oracle AQ monitoring process that is responsable for changing the state from "WAITING" to "READY" (after the delay is expired) wasn't working properly.
For us a database restart fixed this issue.
I faced the same problem, but it was solved after changing these 2 DB parameters:
job_queue_processes (must be > than 0)
aq_tm_processes (autotuning)
Hope it helps.
AQ$_MESSAGES_EXCEPTIONFirst of all I know there's this question: How to clear a queue in Oracle AQ but it doesn't have an answer.
I have a lot of messages(500k) in the exception queue in the Oracle AQ(I didn't know expired messages are moved to another queue so I didn't create a consumer for those). What I need now is to be able to delete those messages fast. I've read that it's not a good idea to clear the queue table via delete, because it could lead to inconsistent state. So I've put together following procedure, but it only clears about 50 messages/second
EXECUTE dbms_aqadm.start_queue(queue_name => 'AQ$_MESSAGES_EXCEPTION',
enqueue => FALSE, dequeue => TRUE);
DECLARE
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
message SYS.AQ$_JMS_MESSAGE;
no_messages EXCEPTION;
pragma exception_init (no_messages, -25228);
BEGIN
dequeue_options.wait := DBMS_AQ.NO_WAIT;
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
LOOP
DBMS_AQ.DEQUEUE(
queue_name => 'AQ$_MESSAGES_EXCEPTION',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
DBMS_OUTPUT.put_line ('Message: ' || message_handle || ' dequeued');
END LOOP;
EXCEPTION
WHEN no_messages THEN
DBMS_OUTPUT.put_line (' ---- NO MORE MESSAGES ---- ');
WHEN others then
DBMS_OUTPUT.put_line ('Exception queue not started for dequeue.');
END;
/
It seems really slow considering it's running on the database machine. This procedure takes about three hours with 500k messages. Can I do it in some more effective manner?
EDIT:
I tried the dequeue_array from the link here: http://www.oracle-developer.net/display.php?id=319
But I can't create the tables, so I'm trying to create an array to "store" the results.
Here's what I've got:
DECLARE
type messages_type is varray(500) of SYS.AQ$_JMS_MESSAGE;
messages messages_type;
dequeue_options DBMS_AQ.dequeue_options_t;
msg_properties DBMS_AQ.message_properties_array_t;
msg_ids DBMS_AQ.MSGID_ARRAY_T;
x_timeout EXCEPTION;
no_messages EXCEPTION;
dequeue_batch PLS_INTEGER := 500;
pragma exception_init (no_messages, -25228);
BEGIN
messages := messages_type();
msg_properties := DBMS_AQ.MESSAGE_PROPERTIES_ARRAY_T();
msg_properties.EXTEND(dequeue_batch);
msg_ids := DBMS_AQ.MSGID_ARRAY_T();
dequeue_options.wait := 5;
LOOP
DBMS_AQ.DEQUEUE_ARRAY(
queue_name => 'AQ$_MESSAGES_EXCEPTION',
dequeue_options => dequeue_options,
array_size => dequeue_batch,
message_properties_array => msg_properties,
payload_array => messages,
msgid_array => msg_ids);
...
I'm getting this error:
wrong number or types of arguments in call to 'DEQUEUE_ARRAY'
I think the problem is in the messages array, but I don't know what to do to make it work. Also, according to oracle doc(http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_aq.htm#i1000850), there should be another parameter:
error_array OUT error_array_t
But the explanation for this parameter is "Currently not implemented". What does it mean? Can it be left out? Should it be set to null? This is really confusing and google doesn't help here :(
If you really want to dequeue, you could probably use the dequeue_array(n) function. That should be much faster.
but the link you provide does have the solution :
-- purge queue
DECLARE
po_t dbms_aqadm.aq$_purge_options_t;
BEGIN
dbms_aqadm.purge_queue_table('MY_QUEUE_TABLE', NULL, po_t);
END;
Otherwise, since this exception queue is created automatically,
I guess you could just drop it, but I am not sure if that is safe
BEGIN
DBMS_AQADM.STOP_QUEUE(
queue_name => 'demo_queue'
);
DBMS_AQADM.DROP_QUEUE(
queue_name => 'demo_queue'
);
DBMS_AQADM.DROP_QUEUE_TABLE(
queue_table => 'demo_queue_table'
);
END;
You can use procedure "purge_queue_table" (as #Stephane said) from dbms_aqadm package but with "purge_condition" parameter specified , with this parameter you can select which messages you delete :
Example :
declare
purge_options dbms_aqadm.aq$_purge_options_t;
begin
purge_options.block := false;
purge_options.delivery_mode := dbms_aqadm.persistent;
dbms_aqadm.purge_queue_table
(queue_table => 'vista.svig_std_tab',
purge_condition => 'qtview.queue = ''AQ$_SVIG_STD_TAB_E'' and qtview.enq_time < to_date(''01.06.2014 00:00:00'',''dd.mm.yyyy hh24:mi:ss'') ',
purge_options => purge_options
);
end;
/
This example deletes messages that are from the specified exception queue and are older than the specified date. It also does this in a much quicker fashion than using "dbms_aq.dequeue" procedure.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PL/SQL function in Oracle cannot see DBMS_AQ
Below is my procedure to enqueue data in a queue, while running the procedure I am getting compilation errors, I can't find where I went wrong. Please help me with solution.
CREATE OR REPLACE PROCEDURE p_enqueue(msg IN VARCHAR2)
AS
PRAGMA AUTONOMOUS_TRANSACTION;
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle RAW(16);
BEGIN
dbms_aq.enqueue( queue_name => 'example_queue',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message_type(msg),
msgid => message_handle);
COMMIT;
END;
ERRORS:
PLS-00201: identifier 'DBMS_AQ' must be declared
PLS-00320: the declaration of the type of this expression is incomplete or malformed
when i try to use grant privilage, i am getting following error
ERROR
ORA-01031: insufficient privileges
If that is the problem i ran the below pl/sql block to enqueue message, the procedure got successfully created.How is it possible if the privilage is not there?
DECLARE
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle RAW(16);
message message_typ;
BEGIN
message := message_typ('NORMAL MESSAGE',
'enqueued to msg_queue first.');
dbms_aq.enqueue(queue_name => 'msg_queue',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
COMMIT;
end;
The error message says that DBMS_AQ is not know. Since this is an Oracle package owned by SYS, it does exist. So you're missing the right to see and execute it.
Have you run
grant EXECUTE ON DBMS_AQ to appuser;
as explicitly shown in my answer to one of your earlier questions?
check the DBMS_AQ pkg and find out which are the mandatory parameters for the procedure which u have used.
below queries 'll be useful for Queue's.
SELECT name, enqueue_enabled, dequeue_enabled
FROM user_queues;
SELECT owner, queue_name, queue_table, consumer_name
FROM dba_queue_subscribers;
SELECT queue_name, consumer_name, address, protocol, delivery_mode, queue_to_queue
FROM user_queue_subscribers;
SELECT qname, destination, start_date, start_time, propagation_window, next_time, latency
FROM user_queue_schedules;
SELECT qname, process_name, session_id, instance, last_run_date, last_run_time, current_start_date
FROM user_queue_schedules;
SELECT qname, current_start_time, next_run_date, next_run_time, total_time, total_number
FROM user_queue_schedules;
SELECT qname, total_bytes, max_number, max_bytes, avg_number, avg_size, avg_time
FROM user_queue_schedules;