МН Пакет / Пакет SQL делаются недействительным

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

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

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

Я думал что, когда я скомпилировал, прежде чем я выполнил сценарий, который зафиксирует любые недопустимые ссылки. Это на 100% восстанавливаемо, и чем больше я использую этот сценарий, тем более раздражающим это становится. Что могло вызвать это, и что зафиксирует его?

(оракул 10 г, с помощью МН Разработчика / Разработчика SQL 7)

24
задан Peter Lang 27 May 2010 в 15:29
поделиться

2 ответа

Background

существующее состояние пакетов было отброшено означает, что у вашего пакета было какое-то состояние.

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

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

Это исключение выбрасывается, чтобы ваши клиенты знали, что они больше не могут полагаться на эти переменные.

Решения

  • По возможности удалите все глобальные переменные и константы (до 11gR2) из тела пакета
  • Замените глобальные переменные функциями DETERMINISTIC (как предлагается в этом ответе)
  • Определение пакетов с PRAGMA SERIALLY_REUSABLE заставляет Oracle заново инициализировать глобальные переменные при каждом обращении к серверу.
  • Закройте сессию и переподключитесь перед повторным вызовом пакета.
  • Сбросьте состояние вручную (см. ответ Пола Джеймса)
21
ответ дан 28 November 2019 в 23:30
поделиться

Если вы запускаете что-то в сценарии, попробуйте эти команды там, прежде чем запускать повторно скомпилированный код ..

exec DBMS_SESSION.RESET_PACKAGE
exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )

Они делают то, что может подсказывать название.

22
ответ дан 28 November 2019 в 23:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: