Question

À l'intérieur d'un déclencheur, je suis en train de boucler sur toutes les colonnes sur une table et comparer les nouvelles valeurs aux anciennes valeurs. Voici ce que j'ai jusqu'à présent:

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;

Le déclencheur compile, mais quand les feux de déclenchement, que je reçois:

  

ORA-01008: toutes les variables liées

sur la première exécution immédiate parce qu'elle attend un rapport qualité-:old. :old et :new sont déjà définis dans le cadre de la détente, mais il semble que execute immédiate ne peut pas voir ces variables.

Yat-il un moyen d'itérer dynamiquement sur les valeurs de la colonne dans un déclencheur?

Était-ce utile?

La solution

Non, vous ne pouvez pas faire référence: anciens et: de nouvelles valeurs dynamiquement. Comme Shane suggère, vous pouvez écrire du code pour générer le code de déclenchement statique, si cela rend la vie plus facile. En outre, vous pouvez faire « faire quelque chose » dans une procédure de package afin que votre déclencheur devient:

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;

(Vous pouvez fossé la clause REFERENCING inutile par la voie).

Autres conseils

Je ne sais pas si vous pouvez faire ce que vous essayez de faire. Quelle est la raison pour laquelle vous ne voulez pas nommer explicitement les colonnes de table à l'intérieur du code PL / SQL? Si les champs de table changent souvent, vous pourriez construire PL / SQL qui construit dynamiquement le déclencheur PL / SQL pour chaque table (avec les noms de champs explicites dans chacun). Chaque fois que les changements de table, vous pouvez exécuter que PL / SQL pour générer le nouveau déclencheur.

Êtes-vous essentiellement essayer de construire votre propre système pour vérifier toutes les modifications apportées à la table? (Ma meilleure estimation de ce que vous pourriez faire avec les anciennes et les nouvelles valeurs de colonnes arbitraires.) Dans ce cas, vous voudrez peut-être se pencher sur ses propres capacités d'audit d'Oracle.

J'ai eu un problème similaire, bien que dans MSSQL.

Ma solution a été d'écrire une procédure stockée qui le compare à des tables et des colonnes d'informations (soit par des vues du dictionnaire ou un référentiel personnalisé) et génère les éléments déclencheurs nécessaires. La procédure doit être exécutée que si le modèle de données change.

L'avantage est que vous n'avez pas à curseur dans le métamodèle dans chaque mise à jour, mais plutôt de générer vos déclencheurs à l'avance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top