我想构建一个列出PL / SQL包的可用对象(过程和函数)的查询,以及另一个列privacy_level,它显示该对象是否存在于body和spec(是公共的)中,或者只在身体内(是私人的)。
浏览一下后,我才发现这个查询(不返回任何行)
select name,
type,
decode(usage,'DECLARATION', 'body only', 'DEFINITION', 'spec and body', usage) defined_on,
line body_line
from all_identifiers ui
where type in ('PROCEDURE', 'FUNCTION')
and usage_context_id = (select usage_id
from user_identifiers
where object_name = ui.object_name
and object_type = ui.object_type
and usage_context_id = 0)
--and object_name = 'PACKAGE_NAME'
--and object_type = 'PACKAGE BODY'
order by name;
提前谢谢。
答案 0 :(得分:1)
您的查询针对all_identifiers
,PLSCOPE_SETTINGS
是the PL/Scope tool的一部分。该系统视图仅显示使用适当设置编译的对象的数据:
默认情况下,PL / Scope不会收集PL / SQL源程序中标识符的数据。要让PL / Scope收集PL / SQL源程序中所有标识符的数据,包括包体中的标识符,请将PL / SQL编译参数
'IDENTIFIERS:ALL'
设置为create package p42 as procedure public_proc; function public_func return number; end p42; / create package body p42 as procedure public_proc is begin null; end public_proc; function public_func return number is begin return 42; end public_func; procedure private_proc is begin null; end private_proc; function private_func return number is begin return 42; end private_func; end p42; /
。
如果我使用默认设置创建包含私有和公共子程序的包:
select name,
...
order by name;
no rows selected
然后您使用查询找不到任何内容:
PLSCOPE_SETTINGS
如果我在创建之前设置了alter session set plscope_settings = 'IDENTIFIERS:ALL';
Session altered.
alter package p42 compile;
Package P42 altered.
,那么它们就会显示出来;假设您不想完全重新创建更改设置后可以重新编译包的所有内容:
NAME TYPE DEFINED_ON BODY_LINE
------------------------------ ------------------ ------------- ----------
PRIVATE_FUNC FUNCTION body only 17
PRIVATE_PROC PROCEDURE body only 12
PUBLIC_FUNC FUNCTION body only 3
PUBLIC_FUNC FUNCTION spec and body 7
PUBLIC_PROC PROCEDURE body only 2
PUBLIC_PROC PROCEDURE spec and body 2
6 rows selected.
现在您的查询得到:
select object_name, type, name,
case min(object_type) when 'PACKAGE BODY' then 'PRIVATE' else 'PUBLIC' end as privacy_level
from user_identifiers
where object_type in ('PACKAGE', 'PACKAGE BODY')
and type in ('FUNCTION', 'PROCEDURE')
group by object_name, type, name
order by object_name, name;
OBJECT_NAME TYPE NAME PRIVACY
--------------- ------------------ --------------- -------
P42 FUNCTION PRIVATE_FUNC PRIVATE
P42 PROCEDURE PRIVATE_PROC PRIVATE
P42 FUNCTION PUBLIC_FUNC PUBLIC
P42 PROCEDURE PUBLIC_PROC PUBLIC
这样的事情可能更接近于你所说的你想要实现的目标,使用私有子程序仅作为正文的一部分出现在表中的事实:
exec dbms_utility.compile_schema(user);
如果要查找所有对象的此信息,可以单独重新编译它们,也可以重新编译整个模式:
All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
但要注意,如果你的任何包有状态,那么当他们调用它们时,现有的会话可能会出错(所以你可能希望在停机期间这样做),并且如果有人编译任何东西而没有明确地改变他们的会话那么那些对象就不会由您查询显示(除非您在数据库级别设置它,这可能是太多的开销)。