Не удается остановить Oracle Queue — не удалось найти вызываемый модуль программы: SYS.DBMS_ASSERT

Невозможно остановить и удалить очередь оракула.
Следующий код

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

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

END;
/

выдает следующие ошибки:

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

Что может быть первопричиной этой проблемы?

ОБНОВЛЕНИЕ:

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

Я проверил таблицу USER_TAB_PRIVS в нескольких наших схемах и вижу, что запись с именем таблицы 'DBMS_ASSERT' существует только в схеме с TEST_USER.
У пользователя есть привилегия EXECUTE.


person Volodymyr Bezuglyy    schedule 07.06.2010    source источник


Ответы (2)


Мне кажется, что либо пакет DBMS_ASSERT не существует (маловероятно, но я полагаю, что это возможно), либо пользователь, которого вы использовали для входа в базу данных, не имеет прав на его выполнение. Обычно PUBLIC предоставляется доступ EXECUTE к DBMS_ASSERT, но, возможно, он был изменен на вашем сайте. Проверьте предоставленные разрешения EXECUTE для DBMS_ASSERT и DBMS_AQADM.

person Bob Jarvis - Reinstate Monica    schedule 07.06.2010
comment
@Vladimir: DBMS_ASSERT вызывается DBMS_AQADM в соответствии с ошибками, показанными в исходном сообщении. - person Bob Jarvis - Reinstate Monica; 07.06.2010
comment
@Vladimir: можете ли вы запустить тест, чтобы увидеть, что произойдет, если вы вызовете процедуру напрямую в DBMS_ASSERT? Попробуйте объявить s VARCHAR2(2000); begin s := DBMS_ASSERT.NOOP('Тестовая строка'); DBMS_OUTPUT.PUT_LINE('s=''' || s || ''''); конец; - person Bob Jarvis - Reinstate Monica; 07.06.2010
comment
@Bob Jarvis: s='Test string' Процедура PL/SQL успешно завершена. - person Volodymyr Bezuglyy; 07.06.2010
comment
@Vladimir: Хорошо, я думаю, это показывает, что ваш тестовый пользователь может успешно выполнять код в DBMS_ASSERT. Но он не работает при вызове из кода в DBMS_AQADM. Не могли бы вы запустить следующее и сообщить мне, каковы результаты? SELECT * FROM DBA_TAB_PRIVS, где table_name IN ('DBMS_AQADM', 'DBMS_ASSERT'); - person Bob Jarvis - Reinstate Monica; 07.06.2010
comment
@Bob Jarvis: TEST_USER SYS DBMS_AQADM SYSTEM ВЫПОЛНИТЬ НЕТ НЕТ - person Volodymyr Bezuglyy; 08.06.2010
comment
@Vladimir: мне любопытно, какие гранты есть на DBMS_ASSERT. Я подозреваю, что пользователь SYS каким-то образом не имеет прав на выполнение DBMS_ASSERT, и поэтому вызов DBMS_ASSERT из DBMS_AQADM завершается ошибкой. DBMS_AQADM — это пакет прав определителя, поэтому он выполняется с правами своего определителя, в данном случае — пользователя SYS. DBMS_ASSERT — это пакет прав вызывающей стороны, который выполняется с правами вызывающей стороны. Я могу ошибаться здесь, но я считаю, что, поскольку DBMS_AQADM (права определителя, как SYS) вызывает DBMS_ASSERT (права вызывающего), SYS должен иметь права выполнения на DBMS_ASSERT. - person Bob Jarvis - Reinstate Monica; 08.06.2010
comment
@Vladimir: это будет зависеть от политики вашего сайта. Как разработчику мне разрешено выполнять SELECT из DBA_TAB_PRIVS там, где я работаю, но ваш сайт может не позволить вам это сделать. Посмотрите, сможете ли вы выполнить следующий запрос: SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME IN ('DBMS_AQADM', 'DBMS_ASSERT'). Если это не удается из-за проблем с разрешениями, вам может потребоваться попросить администратора базы данных запустить его для вас. - person Bob Jarvis - Reinstate Monica; 08.06.2010
comment
@Bob Jarvis: я нашел одно различие между двумя экземплярами оракула. В одном случае правообладателем для TEST_USER является SYSTEM. Но на другом грантодателе для TEST_USER есть SYS. sqlplus TEST_USER/@ora1 SQL› SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME IN ('DBMS_AQADM', 'DBMS_ASSERT') PUBLIC SYS DBMS_ASSERT SYS EXECUTE TEST_USER SYS DBMS_AQADM SYS EXECUTE ', 'DBMS_ASSERT') PUBLIC SYS DBMS_ASSERT SYS EXECUTE TEST_USER SYS DBMS_AQADM SYSTEM EXECUTE - person Volodymyr Bezuglyy; 08.06.2010
comment
@Vladimir: Спасибо за ответ. Похоже, что у PUBLIC есть привилегии EXECUTE в DBMS_ASSERT, поэтому SYS и все остальные должны иметь возможность нормально запускать код в DBMS_ASSERT. (Я не думаю, что праводатель должен иметь значение). Возможно, это неправильный вопрос. @dpbradley, возможно, что-то наткнулся - DBMS_ASSERT (или что-то, что он вызывает) каким-то образом стал недействительным? - person Bob Jarvis - Reinstate Monica; 08.06.2010
comment
@Bob Jarvis: Мы только что обновили Oracle до последнего уровня исправления 10.2.0.5. Теперь у нас нет проблем с очередями. Спасибо за помощь. - person Volodymyr Bezuglyy; 09.06.2010

Если вы делали этот вызов раньше без каких-либо проблем, то ошибка ORA-04068 заставляет меня думать, что что-то в цепочке вызовов было признано недействительным. Вы недавно применяли какие-либо обновления или исправления для установки?

Oracle предоставляет сценарий utlrp в каталоге $ORACLE_HOME/rdbms/admin, который перекомпилирует все пакеты и сообщит обо всех оставшихся недействительными. Пусть ваш администратор запустит это (как SYS).

person dpbradley    schedule 07.06.2010
comment
У нас такая проблема только на одной схеме. Все остальные схемы на том же сервере сегодня работают без ошибок. Но я спрашиваю нашу команду DBA. - person Volodymyr Bezuglyy; 07.06.2010