Удалено существующее состояние пакетов

#sql #oracle #stored-procedures #error-handling #plsql

#sql #Oracle #хранимые процедуры #обработка ошибок #plsql

Вопрос:

Итак, я отлично выполнял процедуру PLSQL и компилировал без ошибок. Я внес одно изменение в свою процедуру, и она по-прежнему компилируется нормально, но теперь, когда я ее запускаю, я получаю эту ошибку:

 ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "SCHEMA.XP_COVER_PAGEP" has been invalidated
ORA-04065: not executed, altered or dropped package body "SCHEMA.XP_COVER_PAGEP"
ORA-06508: PL/SQL: could not find program unit being called: "SCHEMA.XP_COVER_PAGEP"
ORA-06512: at "SCHEMA.XP_ST_002180", line 141
ORA-06512: at line 1
 

Есть идеи, что это может быть? Внесенное мной изменение было настолько незначительным, что я сомневаюсь, что оно могло вызвать эту ошибку. Заранее благодарим вас за помощь!

Ответ №1:

Когда сеанс использует пакет, этот сеанс сохраняет некоторое состояние пакета. Если этот пакет будет перекомпилирован в следующий раз, когда тот же сеанс будет ссылаться на пакет, вы получите эту ошибку.

Чтобы избежать этого, отключите каждый сеанс, который мог использовать пакет, или попросите сеанс выполнить DBMS_SESSION.RESET_PACKAGE для сброса состояния пакета.

Комментарии:

1. Спасибо darreljnz, решение отлично сработало для меня. Но сначала я не понял, что вы говорили. Итак, я просто собираюсь немного прояснить ваше решение для других. Откройте новое окно тестирования в pl / sql и вставьте «Begin sys.dbms_session.reset_package; end;» и нажмите F9, чтобы выполнить его, а затем внесите изменения в свой пакет или перекомпилируйте пакет, и теперь мы не получим никаких ошибок в наших приложениях

2. Лучшее начало ответа на эту проблему. Было бы хорошо, если бы это было продолжено немного дальше, чтобы объяснить основную проблему и причину возникновения ошибки.

3. @YogeshJindal похоже, вы говорите что-то другое, чем darrelinjz. Он написал, что вам нужно запускать RESET_PACKAGE в каждом сеансе после изменения пакета, чтобы избежать ошибки.

4. @PauloManuelSantos Я думаю, он говорит, что либо отключите все сеансы, либо запустите эту команду из сеанса, чтобы сбросить состояние пакета.

5. @YogeshJindal Я прочитал, что для каждого сеанса необходимо запускать эту команду, что имеет смысл после прочтения того, что делает команда, RESET_PACKAGE : «Эта процедура де-создает экземпляры всех пакетов в этом сеансе». Это не должно влиять на другие сеансы в базе данных, поэтому запуск из окна тестирования не повлияет на другие сеансы.

Ответ №2:

Если вы перекомпилируете спецификацию пакета, все зависимые объекты становятся недействительными. Зависимый объект — это любое представление, спецификация пакета, тело пакета, функция или процедура, которые ссылаются на любое из объявлений в перекомпилированной спецификации пакета.

Кроме того, как указал darreljnz, сеансы обычно сохраняют ссылки на состояние пакетов, к которым они обращались, что приводит ORA-04068: existing state of packages has been discarded к тому, что в следующий раз сеанс попытается сослаться на пакет.

Это последнее поведение является реальной неприятностью и делает необходимым либо писать код для повторения операций, либо закрывать все активные сеансы после установки новой версии пакета (фактически перезапуская приложение / службу). Итог: это затрудняет установку исправлений.

Ответ №3:

Используйте pragma serially_reusable в своем пакете и его теле.

Комментарии:

1. что он делает, почему это решение? пожалуйста, уточните

2. Спасибо за совет, но, похоже, это прерывает триггеры, зависящие от пакета.