【发布时间】:2019-04-02 12:01:10
【问题描述】:
我必须找出在我现有的 PL SQL 包中发生插入或更新的表的列表。我开始分析包裹。问题是包代码运行在数千行代码中 调用许多其他包。另外,代码不是我写的。我无法运行 AWR 报告,因为它是开发环境。
有没有办法在启动事务后获取插入/更新发生的表? 可以编写触发器以满足我的要求吗?
【问题讨论】:
标签: sql oracle stored-procedures plsql
我必须找出在我现有的 PL SQL 包中发生插入或更新的表的列表。我开始分析包裹。问题是包代码运行在数千行代码中 调用许多其他包。另外,代码不是我写的。我无法运行 AWR 报告,因为它是开发环境。
有没有办法在启动事务后获取插入/更新发生的表? 可以编写触发器以满足我的要求吗?
【问题讨论】:
标签: sql oracle stored-procedures plsql
-- 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;
【讨论】:
@akk0rd87 有更好的答案——DBA_DEPENDENCIES,用CONNECT BY 来获取被调用过程的表使用情况。
他的答案唯一找不到的是由于动态 SQL 直接使用的表(例如,EXECUTE IMMEDIATE)。为此,您可以使用细粒度审计。
对我来说,这种方法只是您遵循 @akk0rd87 的建议后的一种备份。
由于 SO 不是免费的代码编写服务,我只给你粗略的介绍。
1) 创建一个表作为您的审计跟踪。确保它至少具有以下列:
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 步,但删除策略而不是添加它们。
【讨论】:
不确定触发器是否可以成为解决方案,以下可能是解决方案之一,不过需要一些手动操作:
【讨论】: