#1 Fri 08 July 2022 16:58
- benj25
- Participant occasionnel
- Lieu: Périgueux 24000
- Date d'inscription: 28 Sep 2007
- Messages: 31
TRigger oracle et insert into dans une autre table
Bonjour,
J'ai un petit soucis,
J'ai deux tables, et je souhaiterai que lorsqu'un enregistrement de la première table est complété, il y ai copie vers une deuxième table de l'enregistrement mis à jour.
J'ai fait un trigger en before update for each row
ok j'ai du mal avec les trigger....
mais mon insert into ne passe pas.
Pouvez vous m'aider car je ne vois pas ou cela cloche?
Code:
create or replace TRIGGER SIR_ARBRE_V2_ENT_FAIT_UP after update ON SIR_ARBRE_ENTRETIEN_FUTUR FOR EACH ROW declare CODE_ENT NUMBER(10):=0; O_ID NUMBER(10):=0; begin if (:NEW.ID_ARBRE_ALIGNEMENT_GLD <> :OLD.ID_ARBRE_ALIGNEMENT_GLD ) then select CODE_ENTRETIEN_FUTUR into CODE_ENT from SIR.SIR_ARBRE_ENTRETIEN_FUTUR ; SELECT max(ID_ARBRE_ENTRETIEN_FAIT)+1 into O_ID from SIR.SIR_ARBRE_ENTRETIEN_FAIT; insert into SIR_ARBRE_ENTRETIEN_FAIT (ID_ARBRE_ENTRETIEN_FAIT,CODE_ENTRETIEN_FAIT) VALUES (O_ID,CODE_ENT); insert into SIR_ARBRE_ENTRETIEN_FAIT (ID_ARBRE_ENTRETIEN_FAIT) SELECT max(ID_ARBRE_ENTRETIEN_FAIT)+2 from SIR.SIR_ARBRE_ENTRETIEN_FAIT ; END if; END ;
Par avance merci pour toute aide, car je tourne en rond et ne voit pas mon erreur.
on apprend tous les jours....
Hors ligne
#2 Mon 11 July 2022 12:26
- Alban Kraus
- Participant actif
- Lieu: Tulle (19)
- Date d'inscription: 13 Jan 2022
- Messages: 57
Re: TRigger oracle et insert into dans une autre table
Bonjour,
Je suppose que votre système de gestion de base de données est PostgreSQL dans une version récente. Je suppose que vous n'obtenez pas de message d'erreur (sinon, éditez la question et indiquez-le). Je suppose que vous avez bien mis le code du trigger dans une fonction séparée.
Avez-vous vérifié que le code de votre trigger est bien exécuté ? Que vous rentrez bien dans le IF ? Vous pouvez insérer au début une erreur de logique (par exemple SELECT CHAMP_INEXISTANT; ) ou carrément un message (RAISE 'coucou'; ).
Sans avoir bien cerné votre application, deux choses m'étonnent dans votre code :
Code:
select CODE_ENTRETIEN_FUTUR into CODE_ENT from SIR.SIR_ARBRE_ENTRETIEN_FUTUR;
Avec cette requête, vous sélectionnez la colonne CODE_ENTRETIEN_FUTUR de toutes les lignes de la table SIR_ARBRE_ENTRETIEN_FUTUR, et la première ligne du résultat est enregistré dans la variable CODE_ENT. Ne vouliez-vous pas plutôt écrire :
Code:
SELECT NEW.code_entretien_futur INTO STRICT CODE_ENT;
(Je conseille d'utiliser toujours la syntaxe SELECT ... INTO STRICT variable, qui vérifie que le SELECT renvoie exactement une seule ligne.)
Votre second INSERT rajoute une ligne de valeurs par défaut (NULLs ?) portant l'identifiant O_ID+2 ; à moins que vous ne vouliez que les lignes non-vides aient pour identifiant un multiple de 3 (1, 4, 7, etc.), je ne comprends pas l'intérêt de cette ligne.
Hormis cela, votre premier INSERT me paraît approprié et correct.
Hors ligne
#3 Mon 11 July 2022 15:33
- benj25
- Participant occasionnel
- Lieu: Périgueux 24000
- Date d'inscription: 28 Sep 2007
- Messages: 31
Re: TRigger oracle et insert into dans une autre table
Bonjour,
Merci pour votre aide.
J'ai carrément changé ma façon de procéder comme suit :
Code:
before update ON SIR.SIR_ARBRE_ENTRETIEN_FUTUR FOR EACH ROW before update ON SIR.SIR_ARBRE_ENTRETIEN_FUTUR FOR EACH ROW declare ii number(10):= 0; cd number(10):= 0; te varchar2(250):= ''; de DATE:=''; ida number(10) :=0; um varchar2(200); nae number(10); ent varchar2(250); etat varchar2(250); begin ii := :new.ID_ARBRE_ENTRETIEN_FUTUR; ida := :new.ID_ARBRE_ALIGNEMENT_GLD; cd := :new.code_entretien_futur; te := :new.TYPE_FUTUR_ENTRETIEN; de := :new.DATE_ENTRETIEN; um := :new.UTILISATEUR_MODIF; nae := :new.NOMBRE_ARBRE_ENTRETIEN; ent := :new.ENTREPRENEUR; etat := :new.ETAT_TABLE; If de is not null then insert into SIR_ARBRE_ENTRETIEN_FAIT (ID_ARBRE_ENTRETIEN_FAIT,CODE_ENTRETIEN_FAIT,TYPE_ENTRETIEN,ANCIEN_ID_ENT_FUT,UTILISATEUR_MODIF,NOMBRE_ARBRE_ENTRETIEN,DATE_ENTRETIEN,ENTREPRENEUR) SELECT max(ID_ARBRE_ENTRETIEN_FAIT)+1,cd,te,ii,um,nae,de,ent from SIR.SIR_ARBRE_ENTRETIEN_FAIT ; end if; delete from SIR_ARBRE_ENTRETIEN_FUTUR where DATE_ENTRETIEN is not null; end;
Cependant je n'arrrive pas à 'bloquer' la mise a jour de cette première table (fin du code après le END IF).......
En fait je veux bloquer la mise à jour dans ma table 1 si date_entretien n'est pas vide et copier les données vers la table 2, puis effacer les données de cette enregistrement dans la table 1.
on apprend tous les jours....
Hors ligne
#4 Mon 11 July 2022 18:20
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: TRigger oracle et insert into dans une autre table
Bonsoir,
Il faut faire un "return null" dans la partie de votre fonction trigger pour annuler l'operation du trigger et ne pas faire l'update
Nicolas
Hors ligne
#5 Tue 12 July 2022 14:52
- benj25
- Participant occasionnel
- Lieu: Périgueux 24000
- Date d'inscription: 28 Sep 2007
- Messages: 31
Re: TRigger oracle et insert into dans une autre table
Bonjour,
en Fait j'essaie de copier un enregistrement dans une seconde table si la date n'est pas null ( ou valeur spécifique d'un champs),
Mon premier trigger me le fait trés bien .
Code:
create or replace TRIGGER "SIR_ARBRE_V2_COPIE" after update ON SIR.SIR_ARBRE_ENTRETIEN_FUTUR FOR EACH ROW declare ii number(10):= 0; cd number(10):= 0; te varchar2(250):= ''; de DATE:=''; ida number(10) :=0; um varchar2(200); nae number(10); ent varchar2(250); etat varchar2(250); ct number(10); ctm number(10); begin ii := :new.ID_ARBRE_ENTRETIEN_FUTUR; ida := :new.ID_ARBRE_ALIGNEMENT_GLD; cd := :new.CODE_ENTRETIEN_FUTUR; te := :new.TYPE_FUTUR_ENTRETIEN; de := :new.DATE_ENTRETIEN; um := :new.UTILISATEUR_MODIF; nae := :new.NOMBRE_ARBRE_ENTRETIEN; ent := :new.ENTREPRENEUR; etat := :new.ETAT_TABLE; select count(*) into ct from SIR_ARBRE_ENTRETIEN_FAIT where ANCIEN_ID_ENT_FUT = ii; If de is not null and ct = 0 then insert into SIR_ARBRE_ENTRETIEN_FAIT (ID_ARBRE_ENTRETIEN_FAIT,CODE_ENTRETIEN_FAIT,TYPE_ENTRETIEN,ANCIEN_ID_ENT_FUT,UTILISATEUR_MODIF,NOMBRE_ARBRE_ENTRETIEN,DATE_ENTRETIEN,ENTREPRENEUR) SELECT max(ID_ARBRE_ENTRETIEN_FAIT)+1,cd,te,ii,um,nae,de,ent from SIR.SIR_ARBRE_ENTRETIEN_FAIT ; end if; end;
jusque là pas de soucis. OUFFF çà çà marche.
Mais j'ai un deuxieme trigger qui après un nouvel insert dans ma table 2 vérifie si la donnée existe dans la première table et si oui alors m'efface ma donné de ma première table .
et là Bing table en cours de mutation...
alors que je suis en after update sur le premier trigger et en after insert sur le deuxieme trigger.
Je suis pourtant sur deux trigger différents, l'un après l'autre, donc deux transactions différentes, non ?
Code:
create or replace TRIGGER SIR_ARBRE_V2_ENT_FAIT_UP3 after insert ON SIR.SIR_ARBRE_ENTRETIEN_FAIT FOR EACH ROW declare ii number(10):= 0; ctm number(10); begin ii := :new.ANCIEN_ID_ENT_FUT ; select count(*) into ctm from SIR_ARBRE_ENTRETIEN_FUTUR where ID_ARBRE_ENTRETIEN_FUTUR = ii ; if ctm >0 THEN delete SIR_ARBRE_ENTRETIEN_FUTUR where ID_ARBRE_ENTRETIEN_FUTUR = ii ; end if; end;
J'ai l'impression que mon deuxieme trigger essaie de passer avant mon premiere trigger???
Code:
Erreur lors de l'enregistrement des modifications de la table "SIR"."SIR_ARBRE_ENTRETIEN_FUTUR" : Ligne 2 : ORA-04091: la table SIR.SIR_ARBRE_ENTRETIEN_FUTUR est en mutation ; le déclencheur ou la fonction ne peut la voir ORA-06512: à "SIR.SIR_ARBRE_V2_ENT_FAIT_UP3", ligne 11 ORA-04088: erreur lors d'exécution du déclencheur 'SIR.SIR_ARBRE_V2_ENT_FAIT_UP3' ORA-06512: à "SIR.SIR_ARBRE_V2_COPIE", ligne 32 ORA-04088: erreur lors d'exécution du déclencheur 'SIR.SIR_ARBRE_V2_COPIE'
Je tourne en rond j'ai l'impression....
Sinon faudrait que dans un seul trigger, mon premier trigger si date non null, alors copie dans table 2 ET delete enregistrement en cours de la table 1. mais idem table en mutation....
on apprend tous les jours....
Hors ligne