Oracle PL/SQL:动态循环触发器列

Jos*_*ush 4 oracle plsql dynamic database-trigger

在触发器内部,我试图遍历表格上的所有列,并将新值与旧值进行比较.这是我到目前为止:

CREATE OR REPLACE TRIGGER "JOSH".TEST#UPD BEFORE 
UPDATE ON "JOSH"."TEST_TRIGGER_TABLE" REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
declare    
   oldval varchar(2000);   
   newval varchar(2000);   
begin    
   for row in (SELECT column_name from user_tab_columns where table_name='TEST_TRIGGER_TABLE') loop  
     execute immediate 'select :old.'||row.column_name||' from dual'   into oldval;  
     execute immediate 'select :new.'||row.column_name||' from dual'   into newval;  
     --Do something here with the old and new values
   end loop;  
end;
Run Code Online (Sandbox Code Playgroud)

触发器编译,但是当触发器触发时,我得到:

ORA-01008:并非所有变量都绑定

在第一次执行立即因为它期望值为:old. :old并且:new已经被定义为触发器的一部分,但看起来执行立即数不能看到那些变量.

有没有办法动态迭代触发器中的列值?

Ton*_*ews 5

不,你不能动态地引用:old和:new值.正如Shane建议的那样,您可以编写代码来生成静态触发器代码,如果这样可以使生活更轻松.此外,您可以在程序包过程中"执行此操作",以便您的触发器变为:

CREATE OR REPLACE TRIGGER JOSH.TEST#UPD BEFORE 
UPDATE ON JOSH.TEST_TRIGGER_TABLE
begin    
   my_package.do_something_with (:old.col1, :new.col1);
   my_package.do_something_with (:old.col2, :new.col2);
   my_package.do_something_with (:old.col3, :new.col3);
   -- etc.
end;
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,你可以放弃无意义的REFERENCING子句).