ORA-06508: PL/SQL: не удалось найти вызываемый модуль программы

Я использую оракул 10 г и жабу 11.5. Я пытаюсь вызвать API из анонимного блока.

Если я перекомпилирую API после добавления dbms_output.put_line, а затем попытаюсь выполнить анонимный блок, он покажет ошибку:

"ORA-06508: PL/SQL: could not find program unit being called".

Однако, если я завершу текущий сеанс и открою новый сеанс, анонимный блок будет выполнен без ошибки.

Из-за этой проблемы мне приходится повторно подключать сеанс каждый раз, когда я вношу изменения в API. Может ли кто-нибудь помочь, если эту проблему можно решить, сделав какие-либо конфигурации на уровне жабы или базы данных.


person battech    schedule 15.10.2013    source источник
comment
Вы также получаете что-то вроде «существующее состояние пакета было отброшено»? Если это так, запуск его во второй раз в том же сеансе должен работать. Но это предполагает, что у вашего пакета есть какое-то состояние, то есть переменная, объявленная в пакете, а не в процедуре (и ничего общего с dbms_output).   -  person Alex Poole    schedule 15.10.2013


Ответы (4)


Я подозреваю, что вы сообщаете только о последней ошибке в стеке, например:

ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "schema.package" has been invalidated
ORA-04065: not executed, altered or dropped package body "schema.package"
ORA-06508: PL/SQL: could not find program unit being called: "schema.package"

Если да, то это потому, что в вашем пакете сохраняется состояние:

Значения переменных, констант и курсоров, которые объявляет пакет (либо в его спецификации, либо в теле), составляют его состояние пакета. Если в пакете PL/SQL объявлена ​​хотя бы одна переменная, константа или курсор, то пакет является отслеживающим состояние; в противном случае он не имеет состояния.

При перекомпиляции состояние теряется:

Если тело созданного пакета с отслеживанием состояния перекомпилируется (либо явно, с помощью оператора ALTER PACKAGE, либо неявно), следующий вызов подпрограммы в пакете приводит к тому, что Oracle Database отбрасывает существующее состояние пакета и возбуждает исключение ORA. -04068.

После того, как PL/SQL вызовет исключение, ссылка на пакет заставляет Oracle Database повторно создать экземпляр пакета, который повторно инициализирует его...

Вы не можете избежать этого, если ваш пакет имеет состояние. Я думаю, что довольно редко действительно требуется, чтобы пакет сохранял состояние, поэтому вам следует пересмотреть все, что вы объявили в пакете, но вне функции или процедуры, чтобы увидеть, действительно ли это необходимо на этом уровне. Однако, поскольку вы используете 10g, это включает в себя константы, а не только переменные и курсоры.

Но последний абзац из цитируемой документации означает, что в следующий раз, когда вы будете ссылаться на пакет в том же сеансе, вы не получите ошибку и он будет работать как обычно (пока вы не перекомпилируете его снова).

person Alex Poole    schedule 15.10.2013
comment
Полностью с тобой согласен. Я мог бы заботиться о мнимых числах об этом. Просто запустите этот чертов процесс. Я пытался исключить его из вызывающего анонимного блока, и он обязательно должен завершиться, прежде чем этот волшебный флаг будет снят. Раздражает! - person Pecos Bill; 17.03.2015
comment
Отличное объяснение. У меня было много случаев, когда пакет действителен, явно скомпилирован, попытки вызова предпринимались несколько раз, но все равно получалась эта ошибка. По какой-то причине соединение необходимо отключить и снова подключить, прежде чем он увидит действительный пакет. Этот сценарий можно изящно обработать за одну попытку вызова без возникновения ошибки. Невероятно негативное влияние на любые развертывания, происходящие в крупных корпоративных средах. - person AaronLS; 14.07.2020

кажется, что открытие нового сеанса является ключом.

см. этот ответ.

и вот потрясающее объяснение об этой ошибке

person mkb    schedule 22.09.2014

На основе предыдущих ответов. Я решил свою проблему, удалив глобальную переменную на уровне пакета для процедуры, поскольку в моем случае это не повлияло.

Исходный сценарий был

create or replace PACKAGE BODY APPLICATION_VALIDATION AS 

V_ERROR_NAME varchar2(200) := '';

PROCEDURE  APP_ERROR_X47_VALIDATION (   PROCESS_ID IN VARCHAR2 ) AS BEGIN
     ------ rules for validation... END APP_ERROR_X47_VALIDATION ;

/* Some more code
*/

END APPLICATION_VALIDATION; /

Переписал то же самое без глобальной переменной V_ERROR_NAME и переместил в процедуру на уровне пакета как

Измененный код

create or replace PACKAGE BODY APPLICATION_VALIDATION AS

PROCEDURE  APP_ERROR_X47_VALIDATION (   PROCESS_ID IN VARCHAR2 ) AS

**V_ERROR_NAME varchar2(200) := '';** 

BEGIN
     ------ rules for validation... END APP_ERROR_X47_VALIDATION ;

/* Some more code
*/

END APPLICATION_VALIDATION; /
person friendmanish    schedule 15.10.2015

Я перекомпилировал спецификацию пакета, хотя изменение было только в теле пакета. Это решило мою проблему

person Brian Sebastian    schedule 04.07.2019