views:

209

answers:

2

Cannot stop and drop oracle Queue.
Following code

BEGIN
DBMS_AQADM.STOP_QUEUE (
queue_name => 'TEST_QUEUE');

DBMS_AQADM.DROP_QUEUE(
queue_name => 'TEST_QUEUE');

END;
/

produces following errors:

ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04065: not executed, altered or dropped stored procedure "SYS.DBMS_ASSERT"
ORA-06508: PL/SQL: could not find program unit being called: "SYS.DBMS_ASSERT"
ORA-06512: at "SYS.DBMS_AQADM_SYS", line 3365
ORA-06512: at "SYS.DBMS_AQADM", line 167
ORA-06512: at line 5

What can be the root cause of this problem?

UPDATE:

SQL> SELECT * FROM USER_TAB_PRIVS where table_name='DBMS_ASSERT' and GRANTEE='TEST_USER'
...
GRANTEE=TEST_USER
OWNER=SYS
TABLE_NAME=DBMS_ASSERT
GRANTOR=SYS
PRIVILEGE=EXECUTE
GRANTABLE=NO
HIERARCHY=NO

SQL> SELECT * FROM USER_TAB_PRIVS where table_name='DBMS_AQADM' and GRANTEE='TEST_USER'
...
GRANTEE=TEST_USER
OWNER=SYS
TABLE_NAME=DBMS_AQADM
GRANTOR=SYSTEM
PRIVILEGE=EXECUTE
GRANTABLE=NO
HIERARCHY=NO

I’ve checked the table USER_TAB_PRIVS in a few our schemas and I can see that record with table name 'DBMS_ASSERT' exists in schema with in TEST_USER only.
User have EXECUTE privilege.

+3  A: 

It looks to me like either the DBMS_ASSERT package doesn't exist (unlikely but I suppose possible), or the user you used to log into the database doesn't have execute rights on it. Typically PUBLIC is granted EXECUTE access to DBMS_ASSERT but perhaps it was changed at your site. Check EXECUTE permission grants on DBMS_ASSERT and DBMS_AQADM.

Bob Jarvis
But we do not use DBMS_ASSERT in our code.
Vladimir Bezugliy
@Vladimir: DBMS_ASSERT is being called by DBMS_AQADM, according to the errors shown in the original message.
Bob Jarvis
@Bob Jarvis: See update above.
Vladimir Bezugliy
@Vladimir: can you run a test to see what happens if you invoke a routine in DBMS_ASSERT directly? Try something like declare s VARCHAR2(2000); begin s := DBMS_ASSERT.NOOP('Test string'); DBMS_OUTPUT.PUT_LINE('s=''' || s || ''''); end;
Bob Jarvis
@Bob Jarvis: s='Test string' PL/SQL procedure successfully completed.
Vladimir Bezugliy
@Vladimir: OK, I think that shows your test user can execute code in DBMS_ASSERT successfully. But it doesn't work when called by code in DBMS_AQADM. Could you run the following and let me know what the results are? SELECT * FROM DBA_TAB_PRIVS where table_name IN ('DBMS_AQADM', 'DBMS_ASSERT');
Bob Jarvis
@Bob Jarvis: TEST_USER SYS DBMS_AQADM SYSTEM EXECUTE NO NO
Vladimir Bezugliy
@Vladimir: I'm curious what the grants are on DBMS_ASSERT. I suspect that somehow the SYS user doesn't have execute rights on DBMS_ASSERT and that's why the DBMS_ASSERT call from DBMS_AQADM fails. DBMS_AQADM is a "definer rights" package and thus executes with the rights of its definer which in this case in the SYS user. DBMS_ASSERT is an "invoker rights" package and executes with the rights of the caller. I could be wrong here, but I believe that because DBMS_AQADM (definer rights, as SYS) is calling DBMS_ASSERT (invoker rights) SYS must have execute rights on DBMS_ASSERT.
Bob Jarvis
@Bob Jarvis: who can check rights of SYS user? Only DBA?
Vladimir Bezugliy
@Vladimir: that would depend on your site's policies. As a developer I'm allowed to do a SELECT from DBA_TAB_PRIVS where I work, but your site may not let you do that. See if you can run the following query: SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME IN ('DBMS_AQADM', 'DBMS_ASSERT'). If this fails due to permissions issues you may need to ask a DBA to run it for you.
Bob Jarvis
@Bob Jarvis: I have found one difference between two instances of oracle.On one instance grantor for TEST_USER is SYSTEM.But on another one grantor for TEST_USER is SYS.sqlplus TEST_USER/@ora1SQL> SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME IN ('DBMS_AQADM', 'DBMS_ASSERT')PUBLIC SYS DBMS_ASSERT SYS EXECUTETEST_USER SYS DBMS_AQADM SYS EXECUTEsqlplus TEST_USER/@ora2SQL> SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME IN ('DBMS_AQADM', 'DBMS_ASSERT')PUBLIC SYS DBMS_ASSERT SYS EXECUTE TEST_USER SYS DBMS_AQADM SYSTEM EXECUTE
Vladimir Bezugliy
@Vladimir: Thanks for your response. It looks like PUBLIC has EXECUTE privileges on DBMS_ASSERT, so SYS and everyone else should be able to run code in DBMS_ASSERT just fine. (I don't think that the grantor should matter). Perhaps this is the wrong issue. @dpbradley may have hit upon something - has DBMS_ASSERT (or something it calls) gone invalid somehow?
Bob Jarvis
@Bob Jarvis: We just updated Oracle to the last patch level 10.2.0.5.Now we do not have any problems with queues.Thank you for help.
Vladimir Bezugliy
+1  A: 

If you've made this call before without any problems, then the ORA-04068 error makes me think that something in the calling chain has been invalidated. Have you applied any upgrades or patches to the installation recently?

Oracle supplies a script, utlrp in $ORACLE_HOME/rdbms/admin, that will recompile all of the packages and report on any remaining invalid. Have your administrator run that (as SYS).

dpbradley
We have such problem only on one schema. All other schemas on the same server works today without any errors.But I asks our DBA team.
Vladimir Bezugliy