sql >> Databáze >  >> RDS >> Oracle

Použití OLD a NEW objektu pro dynamické operace uvnitř triggeru

Jedna možnost:Zatlačte na logiku, abyste zkontrolovali, zda je sloupec sledován do procedury f_log, a poté proveďte přes všechny sloupce.

Pokud například vaše track_Table obsahuje (table_name, column_name, allow) hodnoty pro každý sloupec, který chcete sledovat, pak něco takového

 CREATE OF REPLACE PROCEDURE f_log(  p_id          varchar2  
                                    ,p_table_name  varchar2
                                    ,p_column_name varchar2
                                    ,p_old_val     varchar2
                                    ,p_new_val     varchar2)
 as
    l_exists number;
    cursor chk_column_track IS
        SELECT  1
        FROM    track_TABLE           
        WHERE   upper(TABLE_NAME)  = upper(p_table_name)              
        AND     UPPER(column_name) = upper(p_column_name)
        AND     upper(allow) = 'Y'; 
 begin
    open chk_column_track;
    fetch chk_column_track into l_exists;
    if chk_column_track%found then
       --do the insert here
    end if;
    close chk_column_track;
 end;
 /

 CREATE OR REPLACE TRIGGER trg_TRACK 
 AFTER INSERT OR UPDATE OR DELETE ON ABC 
 FOR EACH ROW 
 DECLARE   
      n_id varchar(50); 
 BEGIN   
    n_id := NVL(:old.id, :new.id);   
    -- send all of the values to f_log and have it decide whether to save them
    f_log(:old.id,'COL1',:old.col1,:new.col1);   
    f_log(:old.id,'COL2',:old.col2,:new.col2);   
    f_log(:old.id,'COL3',:old.col3,:new.col3);   
    ... 
 END; 

A pro dobro, umístěte hodnoty ve vaší track_table na insert velkými písmeny, abyste nemuseli UPPER() uložené hodnoty, takže jakýkoli index na těchto hodnotách bude zbytečný!

Nyní to bude žvýkat některé zdroje kontrolující název každého sloupce u každé operace, ale pokud nepoužíváte velké objemy, mohlo by to být zvládnutelné.

Jinak budete potřebovat elegantnější řešení. Jako využití síly kolekcí a klauzule TABLE() k provedení vyhledávání track_table v hromadné operaci. Mějte na paměti, že jsem v tuto chvíli mimo svou databázi, takže jsem tento kód nezkompiloval.

    CREATE OR REPLACE TYPE t_audit_row AS OBJECT (
   p_table_name   varchar2(30)
  ,p_column_name  varchar2(30)
  ,p_id           varchar2(50)
  ,p_old_val      varchar2(2000)
  ,p_new_val      varchar2(2000)
);

CREATE OR REPLACE TYPE t_audit_row_table AS TABLE OF t_audit_row;

CREATE OR REPLACE PROCEDURE f_log (p_audit_row_table t_audit_Row_table)
AS
begin
   -- see how we can match the contents of the collection to the values
   -- in the table all in one query. the insert is just my way of showing
   -- how this can be done in one bulk operation. Alternately you could make
   -- the select a cursor and loop through the rows to process them individually.
   insert into my_audit_log (table_name, column_name, id, old_val, new_val)
   select  p_table_name
          ,p_column_name
          ,p_id
          ,p_old_val
          ,p_new_val
   FROM   track_TABLE TT
         ,table(p_audit_row_table) art
   WHERE  tt.TABLE_NAME   = art.p_table_name                       
   AND    tt.column_name  = art.p_column_name         
   AND    tt.allow        = 'Y';
end;
/

CREATE OR REPLACE TRIGGER trg_TRACK   
AFTER INSERT OR UPDATE OR DELETE ON ABC   
FOR EACH ROW   
DECLARE          
  l_id           varchar(50);   
  l_audit_table  t_audit_row_table;
BEGIN        
  l_id := NVL(:old.id, :new.id);        
  -- send all of the values to f_log and have it decide whether to save them   
  l_audit_table := t_audit_row_table (
                      t_audit_row ('ABC','COL1',l_id, :old.col1, :new.col1)  
                      ,t_audit_row ('ABC','COL2',l_id, :old.col2, :new.col2)  
                      ,t_audit_row ('ABC','COL3',l_id, :old.col3, :new.col3)  
                      ,...  
                      ,t_audit_row ('ABC','COLn',l_id, :old.coln, :new.coln)  
                   );
  f_log(l_audit_table);
end;
/


  1. Uvolněte velmi rozsáhlé databáze

  2. Volání členské funkce na non-objekt - PHP

  3. Zlepšení údržby oddílu pomocí přírůstkové statistiky

  4. Dynamický SQL – EXEC(@SQL) versus EXEC SP_EXECUTESQL(@SQL)