如何查找PL SQL包中受影响的表?

时间:2019-04-02 12:01:11

标签: sql oracle stored-procedures plsql

我必须找出在现有PL SQL程序包中发生插入或更新的表的列表。我开始分析该软件包。值得关注的是,程序包代码在数千行代码中依次运行 调用许多其他程序包。另外,代码不是我写的。由于它是开发环境,因此我无法运行AWR报告。

是否有一种方法可以使在启动事务之后发生插入/更新的表进入? 可以编写触发器来满足我的要求吗?

3 个答案:

答案 0 :(得分:5)

-- plain
select *
from dba_dependencies
where name = 'PACKAGE_NAME' and owner = 'PACKAGE_OWNER'
and type in ('PACKAGE', 'PACKAGE BODY') and referenced_type = 'TABLE';

-- hierarchy
select distinct referenced_owner, referenced_name, referenced_type, referenced_link_name
from dba_dependencies
where referenced_type = 'TABLE'
start with name = 'PACKAGE_NAME' and owner = 'PACKAGE_OWNER' 
and type in ('PACKAGE', 'PACKAGE BODY')
connect by nocycle prior referenced_name = name and prior referenced_owner = owner
and replace(prior referenced_type, 'PACKAGE BODY', 'PACKAGE') = replace(type, 'PACKAGE BODY', 'PACKAGE')
and referenced_owner not in ('SYS', 'SYSTEM', 'OUTLN' , 'AUDSYS')
order by 1, 2, 3;

答案 1 :(得分:2)

@ akk0rd87的答案更好-DBA_DEPENDENCIES,带有CONNECT BY的调用程序可以获取表的用法。

他的答案唯一找不到的是由于动态SQL(例如EXECUTE IMMEDIATE)而直接使用的表。为此,您可以使用细粒度的审核。

对我来说,这种方法只是遵循@ akk0rd87的建议后的备用方法。

由于不是免费的代码编写服务,因此,我将向您简要介绍。

1)创建一个表作为您的审核跟踪。确保它至少包含以下几列:

  • SCHEMA_NAME(30个字符)
  • TABLE_NAME(30个字符)
  • CALL_STACK(4000个字符)
  • SQL_STMT(4000个字符)

2)创建一个包以用作审核处理程序。我将为此提供代码,因为它必须遵循我提供的确切API,才能用于细粒度审核。

CREATE OR REPLACE PACKAGE BODY xxcust_table_access_aud_pkg AS
  PROCEDURE audit_access ( schema_name VARCHAR2, table_Name VARCHAR2, policy_name VARCHAR2 ) IS
  BEGIN
    INSERT INTO your_audit_table ( SCHEMA_NAME, TABLE_NAME, CALL_STACK, SQL_STMT )
    VALUES ( schema_name, 
             table_Name,
             substr(DBMS_UTILITY.format_call_stack,1,4000),
             substr(SYS_CONTEXT ('userenv', 'CURRENT_SQL'),1,4000)
            )
  EXCEPTION
    WHEN others THEN 
      null;
  END;

END xxcust_table_access_aud_pkg ;

3)遍历应用程序模式中的所有表,并为每个表调用DBMS_FGA.ADD_POLICY。例如,

FOR r IN ( ... all my tables ... ) LOOP
  DBMS_FGA.add_policy(object_schema=> r.owner,
                      object_name => r.table_name,
                      policy_Name => -- make up something unique, maybe table_name plus some number,
                      audit_condition => '1=1',
                      audit_column => null,
                      handler_schema => -- your schema,
                      handler_module => 'XXCUST_TABLE_ACCESS_AUD_PKG', -- the package above
                      enable => true);

4)运行程序包并检查表中的结果

5)重复步骤3,但是删除策略而不是添加策略。

答案 2 :(得分:0)

不确定触发器是否可以作为解决方案,下面可能是其中一种解决方案,但需要一些手动操作:

  1. 在主程序包上执行grep查找其他程序包名称,请注意所有程序包的名称,包括主程序包。
  2. 从“ all_source”表中获取所有这些软件包的源代码,并在“ NAME”属性上使用where子句,并指定上面标识的软件包名称。
  3. 将上述软件包的源假脱机到一个文本文件中,并对插入和更新命令执行grep。