Is there any way in Oracle to determine whether a package has state or is stateless? I'm not aware of any view in the data dictionary that contains that information.
The "ORA-04068: existing state of packages string has been discarded" error is rather annoying. It can be eliminated by removing package variables from the package. 11g introduced the feature that a package with variables that are all compile-time constants will be treated as stateless.
I could have two sessions and compile the package in one and call it in the other and see if it throws an exception, but that requires calling a procedure in the package, which may not be desirable.
SQL> SQL> select object_type, status 2 from user_objects 3 where object_name = 'PKG'; OBJECT_TYPE STATUS ----------------------- ------- PACKAGE VALID PACKAGE BODY VALID 2 rows selected. You can see that DDL on EMP (which PKG depends on) made it invalid.
A PL/SQL package consists of two parts: package specification and package body. If the package specification has cursors or subprograms, then the package body is mandatory. Otherwise, it is optional. Both the package body and package specification must be in the same schema.
A package can contain no procedures or functions. It may just contain data types or global variables. 2. A procedure does not return any values in itself, however it can have parameters that can be used to return values as either OUT or modify (IN/OUT).
It sounds like what you want is to be able to list all packages that may potentially have state.
What you're looking for is just packages that have any global variables or constants. For a single package, this is quite simple by inspection. To look across all packages in a schema, however, you could use PL/Scope:
First, log in as the schema owner, turn on PL/Scope in your session:
alter session set plscope_settings='IDENTIFIERS:ALL';
Then, recompile all your package bodies.
Then, run this query to find all the variables and constants declared at the package level:
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'
);
I'd suggest the resulting list of packages will be your target.
If you're on 11gR2, constants no longer cause this problem, so you'd use this query instead:
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'
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With