【发布时间】:2020-06-09 22:17:00
【问题描述】:
我已使用以下查询来获取过程列表,但我只得到架构名称和包名称。如果TYPE Column返回PACKAGE BODY,那么如何获取包内访问表EXCEPTIONAL_INFO的过程名,请帮忙。
SELECT * FROM All_DEPENDENCIES WHERE REFERENCED_NAME = 'EXCEPTIONAL_INFO';
【问题讨论】:
我已使用以下查询来获取过程列表,但我只得到架构名称和包名称。如果TYPE Column返回PACKAGE BODY,那么如何获取包内访问表EXCEPTIONAL_INFO的过程名,请帮忙。
SELECT * FROM All_DEPENDENCIES WHERE REFERENCED_NAME = 'EXCEPTIONAL_INFO';
【问题讨论】:
您可以扫描软件包的源文本。我使用了视图DBA_SOURCE,因为我相信ALL_SOURCE 只显示了我可以执行的程序代码。
CREATE TABLE exceptional_info (i INT);
CREATE OR REPLACE PACKAGE p IS
PROCEDURE a;
PROCEDURE b(table_name VARCHAR2);
END p;
/
CREATE OR REPLACE PACKAGE BODY p IS
PROCEDURE a AS
n NUMBER;
BEGIN
SELECT count(*) INTO n FROM exceptional_info;
END a;
PROCEDURE b(table_name VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||table_name;
END b;
END;
/
您可以找到带有DBA_DEPENDENCIES 的包并扫描这些依赖项的源文本:
SELECT owner, type, name, s.line, s.text
FROM dba_dependencies d
LEFT JOIN dba_source s USING (owner, name, type)
WHERE d.referenced_name = 'EXCEPTIONAL_INFO'
AND upper(s.text) like '%EXCEPTIONAL_INFO%';
OWNER TYPE NAME LINE TEXT
SO PACKAGE BODY P 10 SELECT count(*) INTO n FROM exceptional_info;
您需要从第 10 行向上查找源文本中的过程名称。我现在懒得写代码了。
但是,此方法只能找到静态文本。在示例中找不到PROCEDURE b,它也可以修改表exception_info,而无需硬编码名称。你也需要捕捉这些用法吗?
【讨论】:
你可以试试这个查询:
select owner, object_name, procedure_name
from all_procedures
where object_name =
(
SELECT name FROM All_DEPENDENCIES WHERE REFERENCED_NAME = 'EXCEPTIONAL_INFO'
and type='PACKAGE BODY' and rownum=1
)
;
【讨论】: