这可能不是最好的解决方案,但我已经通过递归使用PL/Scope找到了答案。希望它能帮助有需要的人。:)
create or replace procedure getAllChildCall ( definitionName in char, packageName in char, callLevel in number )
as
begin
for rec in (
with package_tree as (
select * from all_identifiers
where object_name = packageName and object_type = 'PACKAGE BODY'
)
select distinct
name, signature, type, line,
usage, usage_id, usage_context_id
from package_tree
start with (name = definitionName and usage = 'DEFINITION')
connect by prior usage_id = usage_context_id
) loop
if rec.usage = 'CALL' and rec.name not in (
'DEBUG', 'SQLERRM', 'COMMITRECORD', 'ISNOTZERO', 'NVL', 'TRUNC', 'ROUND') then
dbms_output.put_line(LPAD(' ', 2*callLevel, ' ') || rec.name);
getallchildcall(rec.name, packageName, callLevel+1);
end if;
end loop;
end;
/
set serveroutput on
declare
callLevel number;
begin
callLevel := 1;
dbms_output.put_line('start traverse the package child call graph...');
getAllChildCall(upper('YOUR_PROCEDURE_NAME'), upper('YOUR_PACKAGE_NAME'), callLevel);
end;