Существующее состояние пакета отклонено - Oracle - PullRequest
3 голосов
/ 23 июня 2011

Я использую Oracle, и я изменил код для некоторых триггеров и пакета. Когда я запускаю файл сценария, который изменяет код и пытается обновить таблицу (запускающий триггер), я получаю существующее состояние пакета, отбрасываемое

Я получаю кучу ошибок

ORA-04068:
ORA-04061:
ORA-04065:
ORA-06512:--Trigger error -- line 50
ORA-04088:

Эта ошибка возникает только в первый раз. Любые вклады, чтобы избежать этого, будут с благодарностью. Спасибо!

Ответы [ 3 ]

4 голосов
/ 23 июня 2011

serially_reusable имеет смысл только для константных переменных пакета.

Существует только один способ избежать этой ошибки и сохранить производительность (reset_package действительно не очень хороший вариант). Избегайте любых переменных уровня пакета в ваших пакетах PL / SQL. Серверная память вашего Oracle не подходит для хранения состояния.

Если что-то действительно не меняется, это дорого вычислять и возвращаемое значение из функции может многократно использоваться снова и снова без перерасчета, тогда DETERMINISTIC помогает в этом отношении

пример: НЕ ДЕЛАЙТЕ ЭТОГО: varchar2 (100) cached_result;

function foo return varchar2 is
begin
  if cached_result is null then
     cached_result:= ... --expensive calc here
  end if; 
 return cached_result;
end foo;

СДЕЛАЙТЕ ЭТО ВМЕСТО

function foo return varchar2 DETERMINISTIC is
begin
  result:=... --expensive calc here
  return result;
end foo;

Детерминист сообщает Oracle, что для данного ввода результат не изменяется, поэтому он может кэшировать результат и избегать вызова функции.

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

3 голосов
/ 23 июня 2011

Ваш скрипт, скорее всего, кеширует устаревший код. Итак, по ссылке Михаила Паханстова вы можете запустить

DBMS_SESSION.RESET_PACKAGE 

в начале вашего скрипта или используйте

PRAGMA SERIALLY_REUSABLE; 

в вашем скрипте.

Обратите внимание на последствия обоих:

http://download.oracle.com/docs/cd/B13789_01/appdev.101/b10807/13_elems046.htm

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sessio.htm#i1010767

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2298325131459

AskTom в DBMS_SESSION.RESET_PACKAGE:

dbms_session.reset_package, а НАМНОГО быстрее, чем войти и выйти, имеет некоторые последствия для производительности (не как быстро, не делая этого, очевидно!). Это и будет разорвать весь состояние сеанса, например: любые открытые курсоры у вас есть (подготовленные заявления) как хорошо.

AskTom на PRAGMA SERIALLY_REUSABLE:

Это в основном говорит "если вы используете пакет, и вы не сохраняете состояние в этот пакет и хотел бы избежать имея упорство пакета в вашей сессии - меньше памяти - используйте это

0 голосов
/ 30 января 2019

У меня была такая же проблема.

Моя ситуация заключалась в том, что я написал сценарий динамического создания пакета, а затем в следующей строке сценария вызвал процедуру из пакета. Я думаю, что вы находитесь в такой же ситуации.

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

Итак, в сценарии генерации я ввел dbms_lock.wait(2) после строки создания пакета.

Это избавило от проблемы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...