2012-06-14 20 views
9

¿Hay alguna forma en Oracle para determinar si un paquete tiene estado o no tiene estado? No conozco ninguna vista en el diccionario de datos que contenga esa información.¿Hay alguna manera de determinar si un paquete tiene estado en Oracle?

El "ORA-04068: estado existente de los paquetes de cadena se ha descartado" error es bastante molesto. Se puede eliminar eliminando las variables del paquete del paquete. 11g introdujo la característica de que un paquete con variables que son todas constantes de tiempo de compilación se tratará como sin estado.

Podría tener dos sesiones y compilar el paquete en uno y llamarlo en el otro y ver si arroja una excepción, pero eso requiere llamar a un procedimiento en el paquete, que puede no ser deseable.

+1

Antes de responder, ¿puede explicar por qué quiere saber? No tratando de ser un dolor, solo tratando de entender qué es exactamente lo que quieres hacer. ¿Por qué es importante que sepa si el paquete tiene estado? Además, ¿está interesado en saber si un paquete tiene estado y, por lo tanto, podría, en algún momento, encontrarse con ORA-4068? O bien, para un paquete con estado, ¿le interesa saber si el estado actual del paquete es válido, no válido o no inicializado? –

+3

Los paquetes con estado pueden ser molestos porque si se realiza un cambio mientras hay una sesión abierta, puede provocar que los usuarios obtengan errores. Tengo este problema con un paquete, que estaba refactorizando para convertirlo en apátrida y tener algunos problemas (que será el tema de una futura pregunta de SO), por lo que sería bueno tener una manera fácil de saber si el paquete es sin estado o no. Además, qué otros paquetes en la base de datos tienen estado y también podrían causar este problema. – eaolson

Respuesta

11

Parece que lo que quiere es poder enumerar todos los paquetes que pueden tener estado.

Lo que está buscando son solo paquetes que tengan variables o constantes globales. Para un solo paquete, esto es bastante simple por inspección. Para buscar en todos los paquetes en un esquema, sin embargo, se puede utilizar PL/Alcance:

En primer lugar, inicie la sesión como el propietario del esquema, encienda PL/Ámbito de la sesión:

alter session set plscope_settings='IDENTIFIERS:ALL'; 

A continuación, volver a compilar todos sus cuerpos de paquete.

A continuación, ejecute esta consulta para encontrar todas las variables y constantes declaradas en el nivel de paquete:

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' 
); 

me gustaría sugerir la lista resultante de paquetes será su objetivo.

Si estás en 11gR2, constantes ya no causan este problema, por lo que tendría que utilizar esta consulta en su lugar:

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

Eso no es exactamente lo que estoy buscando. En 11g, los paquetes con todas las variables del paquete 'CONSTANT' se consideran apátridas, pero su consulta los devolverá. – eaolson

+0

eaolson, eso no es del todo correcto. En 11gR1, las constantes * do * hacen que el paquete tenga estado; esto fue arreglado en 11gR2. He editado la pregunta para tomar nota de esto. –

+0

Sí, esto funciona! – eaolson

Cuestiones relacionadas