How about using PLSCOPE feature like this (Introduced in Oracle 11g and enhanced in Oracle 12.2 for plscope_settings = statements:all)?
demo@PDB1> alter package pkg compile plscope_settings='identifiers:all,statements:all';
Package altered.
demo@PDB1> alter package pkg compile body plscope_settings='identifiers:all,statements:all';
Package body altered.
demo@PDB1> alter package pkg2 compile plscope_settings='identifiers:all,statements:all';
Package altered.
demo@PDB1> alter package pkg2 compile body plscope_settings='identifiers:all,statements:all';
Package body altered.
demo@PDB1> col routine format a5
demo@PDB1> select t1.owner,t1.name,t1.type,t1.object_name,t1.object_type,t1.usage, t2.text,t2.routine
2 from all_identifiers t1 ,
3 ( select owner,name,type,line,text,
4 last_value( txt2 ignore nulls) over( partition by name,type order by line) as routine
5 from (
6 select owner,name,type,line,text,
7 case when line = 1 then name
8 when lower(trim(text)) like 'function%' then regexp_substr( lower(trim(text)) ,'[[:alnum:]]+',9,1)
9 when lower(trim(text)) like 'procedure%' then regexp_substr( lower(trim(text)) ,'[[:alnum:]]+',11,1)
10 end txt2
11 from all_source
12 where name in ('PKG','PKG2')
13 and owner = user
14 ) ) t2
15 where t1.signature =( select s1.signature
16 from all_identifiers s1
17 where owner = 'SCOTT'
18 and type ='COLUMN'
19 and object_name = 'EMP'
20 and object_type ='TABLE'
21 and name = 'DEPTNO' )
22 and t1.object_name = t2.name(+)
23 and t1.object_type = t2.type (+)
24 and t1.owner = t2.owner (+)
25 and t1.line = t2.line(+)
26 order by 1,4 ;
OWNER NAME TYPE OBJEC OBJECT_TYPE USAGE TEXT ROUTI
----- ------- ------- ----- --------------- --------------- ------------------------------------------------------------ -----
DEMO DEPTNO COLUMN PKG PACKAGE REFERENCE q in out scott.emp.deptno%type); p
DEMO DEPTNO COLUMN PKG PACKAGE BODY REFERENCE select deptno into q from scott.emp; p
DEMO DEPTNO COLUMN PKG PACKAGE BODY REFERENCE select max(deptno) p
DEMO DEPTNO COLUMN PKG PACKAGE BODY REFERENCE q in out scott.emp.deptno%type) is p
DEMO DEPTNO COLUMN PKG2 PACKAGE BODY REFERENCE q in out scott.emp.deptno%type) is p2
DEMO DEPTNO COLUMN PKG2 PACKAGE REFERENCE q in out scott.emp.deptno%type); p2
DEMO DEPTNO COLUMN PKG2 PACKAGE BODY REFERENCE select max(deptno) p2
DEMO DEPTNO COLUMN PKG2 PACKAGE BODY REFERENCE select deptno into q from scott.emp; p2
SCOTT DEPTNO COLUMN EMP TABLE DECLARATION
9 rows selected.
demo@PDB1>
without plscope just scanning through ALL_SOURCE can return false positivies.
in this below package body procedure P3 was added with comments /* scott.deptno */
demo@PDB1> create or replace
2 package body PKG2 is
3 type t is table of number;
4
5 g int;
6
7 function F1
8 return number is
9 begin
10 null;
11 null;
12 null;
13 return 1;
14 end;
15
16 procedure P2(p in number,
17 q in out scott.emp.deptno%type) is
18 begin
19 for i in ( select * from scott.emp )
20 loop
21 null;
22 end loop;
23
24 select deptno into q from scott.emp;
25
26 end;
27
28 procedure p3
29 as
30 begin
31 for x in ( select * from dual /* scott.deptno */ )
32 loop
33 null;
34 end loop;
35 end;
36
37 begin
38 select max(deptno)
39 into g
40 from scott.emp;
41
42 end;
43 /
Package body created.
demo@PDB1> col routine format a5
demo@PDB1> col name format a5
demo@PDB1> col type format a15
demo@PDB1> col text format a60
demo@PDB1> with t as
2 ( select
3 case
4 when line = 1 then name
5 when ltrim(lower(text)) like 'function%' then regexp_substr(substr(ltrim(text),10),'[[:alnum:]]+')
6 when ltrim(lower(text)) like 'procedure%' then regexp_substr(substr(ltrim(text),11),'[[:alnum:]]+')
7 end tag,
8 u.*
9 from user_source u where name in ( 'PKG','PKG2')
10 )
11 select *
12 from (
13 select last_value(tag ignore nulls) over ( partition by name, type order by line ) as routine,
14 name,
15 type,
16 text
17 from t
18 )
19 where lower(text) like '%deptno%';
ROUTI NAME TYPE TEXT
----- ----- --------------- ------------------------------------------------------------
P PKG PACKAGE q in out scott.emp.deptno%type);
P2 PKG2 PACKAGE q in out scott.emp.deptno%type);
P PKG PACKAGE BODY q in out scott.emp.deptno%type) is
P PKG PACKAGE BODY select deptno into q from scott.emp;
P PKG PACKAGE BODY select max(deptno)
P2 PKG2 PACKAGE BODY q in out scott.emp.deptno%type) is
P2 PKG2 PACKAGE BODY select deptno into q from scott.emp;
P2 PKG2 PACKAGE BODY for x in ( select * from dual /* scott.deptno */ ) <<==== This shouldnot be returned.
P2 PKG2 PACKAGE BODY select max(deptno)
9 rows selected.
demo@PDB1>
however using plscope that got eliminated.
demo@PDB1> alter package pkg2 compile body plscope_settings='identifiers:all,statements:all';
Package body altered.
demo@PDB1> select t1.owner,t1.name,t1.type,t1.object_name,t1.object_type,t1.usage, t2.text,t2.routine
2 from all_identifiers t1 ,
3 ( select owner,name,type,line,text,
4 last_value( txt2 ignore nulls) over( partition by name,type order by line) as routine
5 from (
6 select owner,name,type,line,text,
7 case when line = 1 then name
8 when lower(trim(text)) like 'function%' then regexp_substr( lower(trim(text)) ,'[[:alnum:]]+',9,1)
9 when lower(trim(text)) like 'procedure%' then regexp_substr( lower(trim(text)) ,'[[:alnum:]]+',11,1)
10 end txt2
11 from all_source
12 where name in ('PKG','PKG2')
13 and owner = user
14 ) ) t2
15 where t1.signature =( select s1.signature
16 from all_identifiers s1
17 where owner = 'SCOTT'
18 and type ='COLUMN'
19 and object_name = 'EMP'
20 and object_type ='TABLE'
21 and name = 'DEPTNO' )
22 and t1.object_name = t2.name(+)
23 and t1.object_type = t2.type (+)
24 and t1.owner = t2.owner (+)
25 and t1.line = t2.line(+)
26 order by 1,4 ;
OWNER NAME TYPE OBJEC OBJECT_TYPE USAGE TEXT ROUTI
----- ---------- --------------- ----- --------------- --------------- ------------------------------------------------------- -----
DEMO DEPTNO COLUMN PKG PACKAGE BODY REFERENCE q in out scott.emp.deptno%type) is p
DEMO DEPTNO COLUMN PKG PACKAGE BODY REFERENCE select deptno into q from scott.emp; p
DEMO DEPTNO COLUMN PKG PACKAGE BODY REFERENCE select max(deptno) p
DEMO DEPTNO COLUMN PKG PACKAGE REFERENCE q in out scott.emp.deptno%type); p
DEMO DEPTNO COLUMN PKG2 PACKAGE BODY REFERENCE q in out scott.emp.deptno%type) is p2
DEMO DEPTNO COLUMN PKG2 PACKAGE REFERENCE q in out scott.emp.deptno%type); p2
DEMO DEPTNO COLUMN PKG2 PACKAGE BODY REFERENCE select deptno into q from scott.emp; p2
DEMO DEPTNO COLUMN PKG2 PACKAGE BODY REFERENCE select max(deptno) p2
SCOTT DEPTNO COLUMN EMP TABLE DECLARATION
9 rows selected.
demo@PDB1>