0



我正在尝试开发一个触发器来捕获有关表更新的详细信息 - TEST_TABLE。我创建了一个审计表来捕获详细信息,但需要一些方法来获取修改后的列和旧/新值。编写了一个过程 CHECK_VAL 来检查差异,并编写了一个游标来遍历所有列名,由 ":NEW" 和 ":OLD" 伪列连接。

create or replace PROCEDURE CHECK_VAL( 
    L_NEW IN VARCHAR2,
    L_OLD IN VARCHAR2,
    LC_IS_DIFF out varchar2)
IS
BEGIN
    DBMS_OUTPUT.PUT_LINE('IN PROC CHECK_VAL : NEW_VAL '||L_NEW||' OLD: '||L_OLD);

    IF ( L_NEW <> L_OLD OR
        (L_NEW IS NULL AND L_OLD IS NOT NULL) OR
        (L_NEW IS NOT NULL AND L_OLD IS NULL) )
    THEN
         DBMS_OUTPUT.PUT_LINE('IN PROC CHECK_VAL IF');
         LC_IS_DIFF := 'YES';
    ELSE 
         lc_is_diff := 'NO';
    END IF;
END;


/*************/

 create or replace trigger xxtest
    before update on test_table
    for each row
    declare
        ln_cnt number := 0;
        lc_new varchar2(50);
        lc_old varchar2(50);

        lc_col varchar2(50);
        lc_stat varchar2(50);
        cursor lcu_c1 (p_tbl_name varchar2)
        is 
            select column_name
            from user_tab_columns
            where table_name = p_tbl_name;
        lc_column lcu_c1%rowtype;
    begin
        for lc_column in lcu_c1('TEST_TABLE')
        loop
            dbms_output.put_line('In loop ');
            lc_col := lc_column.column_name;
            lc_new := ':NEW.' || lc_col;
            lc_old := ':OLD.' || lc_col;
            check_val(lc_new,lc_old,lc_stat);
            dbms_output.put_line('Column '||lc_col);
            dbms_output.put_line('Changed? '||lc_stat);
            if lc_stat = 'YES' then
                insert into audit_tbl values (sysdate,lc_col);
            end if;
        end loop;
        dbms_output.put_line('Exit trigger');
    end;


/**********/

update test_table
set col2= 'DX'
where col1= 'A';



在表上运行更新后 - TEST_TABLE,输出如下。存在一个问题,因为':NEW.||lc_col1'的 o/p 基本上是一个字符串,其':NEW.column1' INSTEAD 的值为 :NEW.col1。
任何帮助,将不胜感激。

谢谢。!

输出:-

"
1 row(s) updated.
In loop 
IN PROC CHECK_VAL : NEW_VAL :NEW.COL1 OLD: :OLD.COL1
IN PROC CHECK_VAL IF
Column COL1
Changed? YES
In loop 
IN PROC CHECK_VAL : NEW_VAL :NEW.COL2 OLD: :OLD.COL2
IN PROC CHECK_VAL IF
Column COL2
Changed? YES
In loop 
IN PROC CHECK_VAL : NEW_VAL :NEW.COL3 OLD: :OLD.COL3
IN PROC CHECK_VAL IF
Column COL3
Changed? YES
Exit trigger
"
4

1 回答 1

0

您正在将字符串 ':NEW.columnname' 和 ':OLD.columnname' 传递给您的 check_val 过程。然后你正在测试这些字符串是否不同,当然,它们总是不同的(一个有'NEW'作为字符2,3和4,另一个有'OLD')。

您应该传递的是 :NEW.columnname 和 :OLD.column_name 变量中的值。

于 2020-03-04T16:10:53.220 回答