您的查询针对的是all_identifiers,它是the PL/Scope tool 的一部分。该系统视图仅显示使用适当设置编译的对象的数据:
默认情况下,PL/Scope 不会为 PL/SQL 源程序中的标识符收集数据。要让 PL/Scope 收集 PL/SQL 源程序中所有标识符的数据,包括包体中的标识符,请将 PL/SQL 编译参数 PLSCOPE_SETTINGS 设置为 '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);
但请注意,如果您的任何包具有状态,那么现有会话在调用它们时可能会出错(因此您可能希望在停机期间这样做),并且如果有人编译任何东西而不显式更改其会话,那么这些对象将不会由您的查询显示(除非您在数据库级别设置它,这可能开销太大)。