2012-06-14 2 views
9

Есть ли какой-либо способ в Oracle определить, имеет ли пакет состояние или нет апатридов? Я не знаю ни одного представления в словаре данных, который содержит эту информацию.Есть ли способ определить, имеет ли пакет состояние в Oracle?

«ORA-04068: существующее состояние пакетов, строка была отброшена», ошибка довольно раздражает. Его можно устранить, удалив переменные пакета из пакета. 11g представила особенность, что пакет с переменными, которые являются константами времени компиляции, будет рассматриваться как безстоящий.

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

+1

Прежде чем я отвечу, вы можете объяснить, почему вы хотите знать? Не пытайтесь быть болью, просто пытаясь понять, что именно вы хотите сделать. Почему вам важно знать, имеет ли пакет состояние? Кроме того, вам просто интересно узнать, имеет ли пакет состояние, и, следовательно, может в какой-то момент встретиться с ORA-4068? Или, для пакета с состоянием, вас интересует, является ли текущее состояние пакета действительным, недействительным или неинициализированным? –

+3

Пакеты с устаревшими могут быть раздражающими, потому что если изменение происходит во время открытого сеанса, это может привести к ошибкам пользователей. У меня есть эта проблема с одним пакетом, который я рефакторинг сделал апатридом и имел некоторые проблемы (который будет темой будущего вопроса SO), поэтому было бы неплохо иметь простой способ узнать, является ли пакет апатридом или не. Кроме того, какие другие пакеты в базе данных являются работоспособными и могут также вызвать эту проблему. – eaolson

ответ

11

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

Что вы ищете - это просто пакеты, которые имеют любые глобальные переменные или константы. Для одного пакета это довольно просто при осмотре. Для того, чтобы проанализировать все пакеты в схеме, однако, вы можете использовать PL/Scope:

Во-первых, войти в качестве владельца схемы, включите PL/Scope в вашей сессии:

alter session set plscope_settings='IDENTIFIERS:ALL'; 

Затем перекомпилировать все ваши тела упаковки.

Затем запустить этот запрос, чтобы найти все переменные и константы, объявленные на уровне пакета:

select object_name AS package, 
     type, 
     name AS variable_name 
from user_identifiers 
where object_type IN ('PACKAGE','PACKAGE BODY') 
and usage = 'DECLARATION' 
and type in ('VARIABLE','CONSTANT') 
and usage_context_id in (
    select usage_id 
    from user_identifiers 
    where type = 'PACKAGE' 
); 

Я хотел бы предложить получившийся список пакетов будет ваша цель.

Если вы на 11gR2, константы больше не вызывают эту проблему, так что вы будете использовать этот запрос вместо:

select object_name AS package, 
     type, 
     name AS variable_name 
from user_identifiers 
where object_type IN ('PACKAGE','PACKAGE BODY') 
and usage = 'DECLARATION' 
and type = 'VARIABLE' 
and usage_context_id in (
    select usage_id 
    from user_identifiers 
    where type = 'PACKAGE' 
); 
+0

Это не совсем то, что я ищу. В 11g пакеты со всеми переменными пакета CONSTANT считаются апатридами, но ваш запрос вернет их. – eaolson

+0

eaolson, это не совсем правильно. В 11gR1 константы * do * заставляют пакет иметь состояние; это было зафиксировано в 11gR2. Я отредактировал вопрос, чтобы отметить это. –

+0

Yup, это работает! – eaolson

Смежные вопросы