在oracle函数中运行SQL语句时出现错误


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的一部分调用的函数中使用它。

最新更新