【问题标题】:oracle DDL triggeroracle DDL 触发器
【发布时间】:2017-05-15 23:25:12
【问题描述】:

以下是我的查询。我想获取表中新创建的列以用于审计目的。因此,我创建了一个 DDL 触发器来捕获事件。但是触发器不适用于添加的列。正确捕获了删除列事件但没有添加列。有人可以帮我吗? 我尝试使用 'AFTER alter ON SCHEMA' tats 也不起作用。

CREATE OR REPLACE TRIGGER trg_test
   BEFORE CREATE OR ALTER OR DROP ON SCHEMA
DECLARE
   CURSOR get_column_name(i_owner IN VARCHAR2,i_obj_name IN VARCHAR2)
   IS
      SELECT column_name
        FROM all_tab_columns
       WHERE owner = i_owner AND table_name = i_obj_name;

--   pcolumn_name   dba_tab_columns.column_name%TYPE;
BEGIN
   IF (    ora_dict_obj_type = 'TABLE'
       AND ora_sysevent IN ('ALTER')
       AND ora_dict_obj_owner = 'SYS'
      )
   THEN
      FOR x IN get_column_name(ora_dict_obj_owner ,ora_dict_obj_name)
      LOOP
         IF ora_is_drop_column (x.column_name)
         THEN
            dbms_output.put_line('Deleted column :' || x.column_name);
         END IF;
         IF ora_is_alter_column (x.column_name)
         THEN
            dbms_output.put_line('Newly added column :' || x.column_name);
         END IF;
      END LOOP;

   END IF;
END;
/

【问题讨论】:

    标签: plsql triggers


    【解决方案1】:

    实际上,触发器被触发了,唯一的问题是 Oracle 没有 ora_is_new_column 函数或类似的东西。至少我什么都找不到……

    对于我的测试用例,当我执行“alter table aaa modify (colbbb...)”时,ora_is_alter_column 可以正常工作。

    我能想到的最佳替代方法是记录“更改表语句”:

    CREATE OR REPLACE TRIGGER ddl_trigger
    BEFORE ALTER ON SCHEMA
    DECLARE
     v_sql_text_list  dbms_standard.ora_name_list_t;
     v_sql_text_count binary_integer;
    BEGIN
      v_sql_text_count := ora_sql_txt(v_sql_text_list);
      for v_i in 1..v_sql_text_count 
      loop
        dbms_output.put_line('sqltext(' || v_i || ')=' || v_sql_text_list(v_i));
      end loop;
    END ddl_trigger;
    /
    

    【讨论】:

    • 谢谢.. 有没有其他方法可以获得新添加的列?
    • 嗯,一种可能性是分析在触发器中捕获的 DDL 并提取列名或列(可以在同一 sql 中添加多个列,例如:alter table dll_trg_test add (descr2 varchar2(100 char), descr3 varchar2(400 char)) modify (descr varchar2(1000 char)); 另一种可能性是捕获前触发器中的列(并将其保存到某个“全局”区域,例如:包变量),并异步启动作业。在作业中,您可以将实际列与保存的集合进行比较。
    • 我自己没有尝试过上述任何一种方法。他们说,需要异步作业,因为有时新列在 user_tab_columns 中不可用,甚至在 after 触发器中也不可用。至少这是我在研究中发现的。 :)
    猜你喜欢
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 2018-12-15
    • 2019-07-26
    • 2015-12-11
    • 2021-02-01
    相关资源
    最近更新 更多