【问题标题】:How to get the name of stored procedure within a package and a schema accessing a particular table in Oracle?如何获取包中存储过程的名称和访问 Oracle 中特定表的模式?
【发布时间】:2020-06-09 22:17:00
【问题描述】:

我已使用以下查询来获取过程列表,但我只得到架构名称和包名称。如果TYPE Column返回PACKAGE BODY,那么如何获取包内访问表EXCEPTIONAL_INFO的过程名,请帮忙。

SELECT * FROM All_DEPENDENCIES WHERE REFERENCED_NAME = 'EXCEPTIONAL_INFO';

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您可以扫描软件包的源文本。我使用了视图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,而无需硬编码名称。你也需要捕捉这些用法吗?

    【讨论】:

    • all_procedures 显示包中的程序,因此您不必扫描 all_source
    • @sandman,是的,但您不知道包中的哪些过程正在访问表 EXCEPTIONAL_INFO
    • 好点。查询将需要更多的工作。这比我现在想做的更努力:)
    • 我不需要你提到的程序 b,我的工作是根据你的查询完成的,谢谢
    • 干得好。这是静态代码的优点之一。只需确保找到表名的大小写拼写即可。
    【解决方案2】:

    你可以试试这个查询:

        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
          )
        ;
    

    【讨论】:

    • 我也不知道架构,我必须在整个数据库中搜索表的使用位置,所以我不能简单地对架构/对象名称进行过滤。在 OP 中,我想要 schema.package_name.procedure_name
    • 现在您要我为您编写联接吗?我现在将编辑我的答案。请注意,子查询可以返回多行,因此我使用 rownum=1 对其进行了测试,以找到引用的第一个包。
    • @sandman: ALL_DEPENDENCIES 显示哪个包使用该表,但不显示包中的哪个过程。您的查询显示包的 所有 过程,无论它们是否使用该表。
    • SELECT A.OWNER,A.OBJECT_NAME,A.PROCEDURE_NAME FROM ALL_PROCEDURES A ,All_DEPENDENCIES B WHERE A.OBJECT_NAME=B.NAME AND A.OWNER=B.OWNER AND B.REFERENCED_NAME = 'EXCEPTIONAL_INFO' AND B.TYPE='PACKAGE BODY' AND A.PROCEDURE_NAME 不为空
    • 查询好吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多