Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle PL/SQL: Loop Over Trigger Columns Dynamically

Inside of a trigger I'm trying to loop over all columns on a table and compare the new values to the old values. Here is what I have so far:

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;

The trigger compiles, but when the trigger fires, I'm getting:

ORA-01008: not all variables bound

on the first execute immediate because it's expecting a value for :old. :old and :new are already defined as part of the trigger, but it appears that execute immediate can't see those variables.

Is there a way to dynamically iterate over the column values in a trigger?

like image 426
Josh Bush Avatar asked Dec 08 '22 07:12

Josh Bush


2 Answers

No, you cannot reference :old and :new values dynamically. As Shane suggests, you can write code to generate the static trigger code, if that makes life easier. Also, you can make "do something here" into a package procedure so that your trigger becomes:

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;

(You can ditch the pointless REFERENCING clause by the way).

like image 92
Tony Andrews Avatar answered Dec 20 '22 10:12

Tony Andrews


I'm not sure if you can do what you are trying to do. What is the reason you don't want to explicitly name the table columns inside the PL/SQL code? If the table fields are changing often, you could build PL/SQL that dynamically builds the PL/SQL trigger for each table (with the explicit field names in each). Each time the table changes, you could run that PL/SQL to generate the new trigger.

like image 34
Shane Avatar answered Dec 20 '22 11:12

Shane