2012-06-28 71 views
0

该触发器提议跟踪客户表上的旧值和新值。 它只为每个更改的值列插入一个新行。 想象一下,有二十五列,我得写25次相同的东西。 有没有什么办法可以做到这一点在循环或更好的方式来保持更通用。想象一下,如果有任何新的客户添加到客户表中,用您告诉我的方式将不需要更改触发器。遍历oracle表中的列

CREATE OR REPLACE TRIGGER KRD_CUSTOMER_UPD_DEL_TRG 
     BEFORE UPDATE OR DELETE ON KRD_CUSTOMER 
     FOR EACH ROW 
    DECLARE 
     V_ISLEMTIPI VARCHAR2(1); 
    BEGIN 
     IF UPDATING THEN 
      if  :OLD.CUSTOMERNAME <> :NEW.CUSTOMERNAME then 
     krd_ins_customerTable(p_OldCustomerName => :OLD.CUSTOMERNAME, 
            p_NewCustomerName => :NEW.CUSTOMERNAME); 
     end if; 
     end if; 

    end; 
+1

FWIW,你可能想明确地在你的触发器中处理'CUSTOMERNAME'的NULL值。 – Ollie

+0

最实用的方法是动态创建静态触发器。 (这是使用SQL来生成触发器。)blgnkc提供了Tom Kyte解决方案的链接,作为对Rene答案的评论。 http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055 – spencer7593

回答

0

列名在视图中可用:user_tab_columns。

可能工作的东西: 在此视图中遍历列名称并构造一个包含必须为该特定列执行的语句的字符串。

l_statement := 'begin if :OLD.<columname> <> :NEW.<columname> then 
     krd_ins_customerTable(p_Old<columname> => :OLD.<columname>, 
            p_New<columname> => :NEW.<columname>); end;' 

execute immediate l_statement; 

As Ollie已评论:要检查不等式还检查空值。

If (a is null and b is not null) 
or (a is not null and b is null) 
or (a is not null and b is not null and a!=b) 
+1

@ http://asktom.oracle.com/pls/asktom/f?p= 100:11:0 :::: P11_QUESTION_ID:59412348055它说不可能:( – theklc

+0

感谢。 – Rene

+1

即使你可以得到这个工作,出于性能原因,你真的想要避免对USER_TAB_COLUMNS的递归调用和开销的EXECUTE IMMEDIATEs,这只是很多繁重的工作,让数据库做FOR EACH ROW改变了,我第二次评论blgnklc。使用Tom Kyte的方法。 – spencer7593