#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. Спасибо за совет, но, похоже, это прерывает триггеры, зависящие от пакета.