create or replace function auditif
return number as
l_filter_count NUMBER;
begin
EXECUTE IMMEDIATE 'EXPLAIN PLAN FOR ' || SYS_CONTEXT('USERENV','CURRENT_SQL');
select count(*)
into l_filter_count
from table(dbms_xplan.display(format=>'PREDICATE'))
where (plan_table_output like '% - filter(%' OR plan_table_output like '% - access(%')
and plan_table_output not like '%SYS_AUDIT(%';
dbms_output.put_line(l_filter_count);
if (SUBSTR(UPPER(sys_context('userenv','CLIENT_PROGRAM_NAME')),1,3)='SQL' AND l_filter_count=0)
or
(SUBSTR(UPPER(sys_context('userenv','CLIENT_PROGRAM_NAME')),1,4)='TOAD' AND l_filter_count=0)
then return 1;
else return 0;
end if;
end;
/
我在DBMS_FGA策略中调用了这个函数,用于有条件地启用审计
begin
DBMS_FGA.ADD_POLICY(
OBJECT_SCHEMA =>'AIM_DBA',
object_name =>'EMP_DATA_I',
policy_name =>'PROTECT_AIM_DBA_SCHEMA_TABLE',
audit_condition=>'AIM_DBA.AUDITIF=1',
statement_types =>'UPDATE,DELETE');
end;
/
但是当运行sql语句检查审计策略功能时,出现以下错误:
delete EMP_DATA_I
*
ERROR at line 1:
ORA-00905: missing keyword
ORA-06512: at "AIM_DBA.AUDITIF", line 5
上下文调用的结果似乎为null,因此您尝试运行
explain plan for
作为完整语句,for
;这会抛出错误
从DBMS_FGA文档:
audit_condition必须是一个布尔表达式,可以使用插入、更新或删除的行中的值进行计算。表达式也可以使用函数,如USER或SYS_CONTEXT函数。
表达式不能使用"与"、"或"等运算符组合条件。audit_condition可以为NULL(或省略),它被解释为TRUE,但它不能包含以下元素:
- 子查询或序列
- 使用SYS_CONTEXT函数访问USERENV命名空间时的以下属性:
- CURRENT_SQL
- CURRENT_SQL_LENGTH
- CURRENT_BIND
- 任何伪列LEVEL, PRIOR,或ROWNUM的使用
在sys_context
文档中:
CURRENT_SQL
返回触发细粒度审计事件. ...的当前SQL的前4K字节您只能在细粒度审计特性的事件处理程序中指定这些属性。
因此您可以在handler_module
函数中使用它,但不能在您作为audit_condition
的一部分调用的函数中使用它。