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:
- 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.
- Il trigger viene creato dopo che abbiamo versionato la tabella e quindi occorre creare il trigger utilizzando la corretta procedura.
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