lunedì 26 gennaio 2015

OWM - Creare e gestire Trigger

Il prodotto OWM utilizza di per se dei trigger instead off per la gestione del versionamento delle tabelle oracle. Nel momento in cui l'utente decide di utilizzare trigger sulle tabelle versionate per operazioni proprie occorre definire bene come crearli.
Da documentazione abbiamo quanto segue:

"Triggers on Version-Enabled Tables
Version-enabled tables can have triggers defined; however, the following considerations and restrictions apply:
■ Only per-row triggers are supported. Per-statement triggers are not supported.
■ The only call-out supported is to PL/SQL procedures. That is, the action_type  must be PL/SQL.
Any triggers that are not supported for version-enabled tables are deactivated when
versioning is enabled, and are activated when versioning is disabled. "

Una volta che un trigger viene creato su una tabella versionata, questo diventa parte integrante dei trigger di prodotto utilizzati per la gestione del versionamento, quindi non li troviamo più sulle tabelle di sistema ALL_TRIGGERS ma bensi su quelle del prodotto WMSYS.ALL_WM_TAB_TRIGGERS o WMSYS.WM$UDTRIG_INFO.

Adesso nasce una domanda, come si creano i trigger su una tabella versionata?
A questa domanda vi sono due risposte:
  1. Il trigger si crea prima di versionare la tabella, in tal modo nel momento in cui versioniamo la tabella questo viene inglobato e gestito dal prodotto.
  2. Il trigger viene creato dopo che abbiamo versionato la tabella e quindi occorre creare il trigger utilizzando la corretta procedura.
 Di seguito un esempio di come creare un trigger sopo che la tabella è stata versionata.

 begin
  DBMS_WM.BeginDDL('PIPPO.ARCHIVE');
end ;

CREATE OR REPLACE TRIGGER
PIPPO.TRG_ARCHIVE_UPD_CUBEID AFTER
  INSERT ON "
PIPPO"."ARCHIVE_LTS" REFERENCING NEW AS NEW FOR EACH ROW BEGIN
  UPDATE
PIPPO.ARCHIVE
  SET CUBEID         =:NEW.LOCALID
  WHERE OBJECTTYPE   =:NEW.OBJECTTYPE
  AND COMMUNITYID    =:NEW.COMMUNITYID
  AND CONTEXTID      =:NEW.CONTEXTID
  AND ARCHIVECONSTRID=:NEW.ARCHIVECONSTRID
  AND ARCHIVEID      =:NEW.ARCHIVEID
  AND LOCALID        =:NEW.LOCALID
  AND (CUBEID IS NULL OR CUBEID <> :NEW.LOCALID);
END ;

begin
  DBMS_WM.CommitDDL('
PIPPO.ARCHIVE');
end ;









Di seguito alcune query da eseguire per verificare la corretta creazione del trigger.

select trigger_name,trigger_type,triggering_event,table_name 
  from all_triggers 
where trigger_name = 'TRG_ARCHIVE_UPD_CUBEID';

select * 

  from ALL_WM_TAB_TRIGGERS 
where trigger_name = 'TRG_ARCHIVE_UPD_CUBEID';

select * 

  from WMSYS.WM$UDTRIG_INFO 
where trigger_name = 'TRG_ARCHIVE_UPD_CUBEID';

Poichè il versionamento delle tabelle si basa sulla pk di ogni tabella, a cui viene aggiunto il campo VERSION, diventa impossibile effettuare un update su un campo che appartiene alla chiave. Per poter modificare un campo della chiave occorre cancellare la vecchia chiave ed inserire la nuova, in tal modo si ha un nuovo record ed una nuova storia.
Come fare questo senza dover ogni volta effettuare una delete/insert, si può pensare di creare un trigger di INSTEAD OF UPDATE, in cui l'operazione di update viene sostituita da una delete/insert. Questo tipo di trigger si possono creare solo sulle viste e nel caso di tabelle versionate sulla vista che ha lo stesso nome della tabella che abbiamo versionato. Dove sta il problema? Che nel caso in cui vengano fatte operazione di tipo BEGINDDL ecc.. poichè queste ricreano le viste di prodotto il trigger si perde e và ricostruito ogni volta.
A questo punto se farlo o  non farlo lo lascio a voi decidere.... di seguito un esempio di come creare questo trigger:

CREATE OR REPLACE TRIGGER PIPPO.TRIG_ARCHIVE_UPD
INSTEAD OF UPDATE ON
PIPPO.ARCHIVE REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
                DELETE FROM
PIPPO.ARCHIVE
                WHERE PK=OLD.<PK>;
                

IF(SQL % ROWCOUNT > 0) THEN
                               

INSERT INTO PIPPO.ARCHIVE
   (<CAMPI>)
  VALUES
  (:NEW.<CAMPI>);
                

END IF;
END;










Nessun commento:

Posta un commento