如何修改此触发器以包含column-name,old-value和new-value?

时间:2016-01-27 23:22:17

标签: sql oracle logging triggers

假设,一个触发器跟踪AREA - 表并记录AREA_LOGGING_TABLE中的更改。

 CREATE TABLE AREA
   (    AREA_NUMBER NUMBER, 
    AREA_NAME VARCHAR(20)
   )

CREATE TABLE AREA_LOGGING_TABLE 
   (    WHO_MODIFIED VARCHAR(20), 
    WHEN_MODIFIED DATE, 
    OLD_VALUE BLOB, 
    NEW_VALUE BLOB, 
    COLUMN_NAME VARCHAR(30)
   )

我想记录用户名,日期时间,列名,旧数据和新数据。

我该怎么做?

CREATE OR REPLACE TRIGGER AREA_MODIFY_LOGGER_COLUMN_LVL 
        AFTER INSERT or UPDATE or DELETE
            ON AREA 
            REFERENCING OLD AS old_data NEW AS new_data 
            FOR EACH ROW  
        DECLARE
            v_username varchar2(10);

        BEGIN

           -- Find username of person performing the DELETE on the table
           SELECT user INTO v_username
           FROM dual;

           -- Insert record into audit table
           INSERT INTO AREA_LOGGING_TABLE(who_modified, when_modified, old_value, new_value)
           VALUES ( v_username, sysdate, :old_data.area_number, :new_data.area_number);

       END;

这不起作用。

此外,我不知道如何在这里包含列名。

2 个答案:

答案 0 :(得分:0)

utl_raw.cast_to_raw功能可用于将您的值转换为BLOB。 关于column_name,我认为您可以在插入语句中对其进行硬编码,因为您已在:NEW:OLD之后执行此操作。

nvl函数用于处理:NEW \ :OLD中的空值。

   CREATE OR REPLACE TRIGGER AREA_MODIFY_LOGGER_COLUMN_LVL 
            AFTER INSERT or UPDATE or DELETE
                ON AREA 
                REFERENCING OLD AS Old NEW AS New
                FOR EACH ROW  
            DECLARE
                v_username varchar2(10);

            BEGIN

               -- Find username of person performing the DELETE on the table
               SELECT user INTO v_username
               FROM dual;


                if nvl(:old.area_number, -1) <> nvl(:new.area_number, -1) then
                   -- Insert record into audit table
                   INSERT INTO AREA_LOGGING_TABLE(who_modified, when_modified, old_value, new_value, column_name)
                   VALUES ( v_username, sysdate, utl_raw.cast_to_raw(:Old.area_number), utl_raw.cast_to_raw(:New.area_number), 'AREA_NUMBER');
                end if;

               if nvl(:old.area_name , '-1')  <> nvl(:new.area_name, '-1')   then
               -- Insert record into audit table
                INSERT INTO AREA_LOGGING_TABLE(who_modified, when_modified, old_value, new_value, column_name)
                VALUES ( v_username, sysdate, utl_raw.cast_to_raw(:Old.AREA_NAME), utl_raw.cast_to_raw(:New.AREA_NAME), 'AREA_NAME');
              end if;

       END;

答案 1 :(得分:0)

只是为了简要介绍触发器以增强触发器的概念 当触发器触发时,你有下面由SQL创建的内置表。 - 删除(即从已删除的d中选择@ empid = d.Emp_ID) - 插入(即从插入的i中选择@ empid = i.Emp_ID)(可用于插入/更新操作)