用于添加新表进行审计的 Oracle 触发器

问题描述 投票:0回答:1

我正在尝试创建一个触发器,该触发器在名为“HK”的特定模式中创建新表后触发。 背景:HK 模式的所有表都需要对其进行 INSERT、UPDATE 和 DELETE 操作进行审核。还有将来创建的所有表格。

我之前创建了一个名为“changes_on_hk”的审核策略。为此,我只使用该模式的一张表

create audit policy changes_on_hk actions insert, update, delete on hk.TABLE_001;

通过这个小程序,我将所有其他表放入此审计策略中

DECLARE
  l_sql_stmt varchar2(1000);
BEGIN
  FOR t IN (SELECT owner, table_name FROM all_tables WHERE upper(owner) = 'HK')
  LOOP
    l_sql_stmt := 'alter audit policy changes_on_hk add actions insert, update, delete on ' || t.owner || '.' || t.table_name;
    EXECUTE IMMEDIATE l_sql_stmt;
  END LOOP;
END;
/

这是我未来情况的触发器,当在 HK 模式中创建新表以使这些表直接进行审计时

CREATE OR REPLACE TRIGGER SYSTEM.CHECK_HK_TABLES_FOR_AUDIT
AFTER CREATE ON SCHEMA
DECLARE
  l_sql_stmt varchar2(1000);
  v_schema_name varchar2(100);
  v_table_name varchar2(100);
BEGIN
  v_schema_name := ora_dict_obj_owner;
  v_table_name := ora_dict_obj_name;
  
  IF v_schema_name = 'HK' THEN
    l_sql_stmt := 'alter audit policy changes_on_hk add actions insert, update, delete on ' || v_schema_name || '.' || v_table_name;
    EXECUTE IMMEDIATE l_sql_stmt;
    END IF;
END;
/
ALTER TRIGGER SYSTEM.CHECK_HK_TABLES_FOR_AUDIT ENABLE;

现在我尝试在模式 HK 中以不同用户身份创建一个测试表(在本例中我采用系统)

CREATE TABLE HK.TEST_DAVID_SYSTEM
(
    column_1 number,
    column_2 varchar2(5)
);

并作为架构 HK 中的用户 HK

CREATE TABLE HK.TEST_DAVID_HK
(
    column_1 number,
    column_2 varchar2(5)
);

此后,我查看此 SQL,看看新表是否在我的审计策略中

select upper(table_name) from all_tables where upper(owner) = 'HK'
minus
select upper(object_name) from audit_unified_policies where lower(policy_name) in ('changes_on_hk');

但他们不是。我错过了什么吗?

oracle audit
1个回答
0
投票

我现在找到了这种方式来满足我的需求。

我使用数据库触发器后创建,因为模式触发器看起来像是当用户是模式时才触发的。

由于 Oracle 不允许直接在触发器中放弃审核策略命令,我创建了一个在触发器中的作业中执行的过程,如本博客所示 https://dioncho.wordpress.com/2009/03/ 09/在 ddl 触发器中执行 ddl/

CREATE OR REPLACE PROCEDURE SYS.EXEC_AUDIT_STMT(l_sql_stmt in varchar2)
IS
BEGIN
  EXECUTE IMMEDIATE l_sql_stmt;
END;
/

CREATE OR REPLACE TRIGGER SYS.CHECK_HK_TABLES_FOR_AUDIT
AFTER CREATE ON DATABASE
DECLARE
  l_sql_stmt varchar2(1000);
  v_job number;
BEGIN
  IF ora_dict_obj_owner = 'HK' and ora_dict_obj_type = 'TABLE' THEN
    l_sql_stmt := 'alter audit policy changes_on_hk add actions insert, update, delete on ' || ora_dict_obj_owner || '.' || ora_dict_obj_name;
    DBMS_JOB.SUBMIT(v_job, 'EXEC_AUDIT_STMT(''' || l_sql_stmt || ''');', sysdate+(1/24/60/60));
  END IF;
END;
/
ALTER TRIGGER SYS.CHECK_HK_TABLES_FOR_AUDIT ENABLE;

首先我尝试通过 DBMS_SCHEDULER 执行该作业,因为 DBMS_JOB 是旧类。但那项工作不想运行。也许我稍后会调查一下。

© www.soinside.com 2019 - 2024. All rights reserved.