Oracle PL / SQL触发器,在UPDATE之前/之后仅用于识别表中已修改的列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle PL / SQL触发器,在UPDATE之前/之后仅用于识别表中已修改的列相关的知识,希望对你有一定的参考价值。

我正在尝试开发触发器以捕获有关表-TEST_TABLE的更新的详细信息。我已经创建了一个审计表来捕获详细信息,但是需要某种方式来选择ONLY修改后的列和旧/新值。已经编写了一个过程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
"
答案

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

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

以上是关于Oracle PL / SQL触发器,在UPDATE之前/之后仅用于识别表中已修改的列的主要内容,如果未能解决你的问题,请参考以下文章

使用 PL\SQL Developer 7.0.2 调试 Oracle 触发器?

pl/sql--触发器 Triggers

ORACLE PL/SQL 触发器的编程问题

ORACLE PL/SQL 触发器使用两个不同的表

在 Oracle PL/SQL 中创建触发器时如何解决“编译错误成功”错误?

PL/SQL ORACLE:删除时触发更新