exception TABLE IS MUTATING [ORACLE - TRIGGER] - SQL/NoSQL - Programmation
Marsh Posté le 16-06-2008 à 18:42:09
oui tout a fait. C'est cette ligne la qui merde
"SELECT COUNT(*) INTO rowcnt FROM t_CEDD_MAIN m WHERE m.PersonIdNo = :new.PersonIdNo;"
Ne me dit pas qu'il n'y a pas moyen, c'est des conneries ça
ton trigger est ultra mal foutu.
donc ce que tu fais la, c'est avant chaque insert ou update dans ta table, tu redéclenche un insert ou un update automatiquement? Tu sais que c'est complètement abérant?
Ce genre de trigger, c'est pour modifier la ligne qui est en cours d'insertion ou de modification, pour pour générer encore une panoplie de data dans la même table.
Marsh Posté le 16-06-2008 à 18:58:44
Il faut bien pouvoir faire le test si ma ligne est un nouvel employé ou non. Si je le fais pas dans mon trigger ou le faire. Je doute pas un instant que mon trigger est nul, c'est le premier que j'ecris.
Marsh Posté le 16-06-2008 à 20:23:38
la preuve que tu n'as rien compris aux trigger ;-)
Je me permets de te renvoyer vers la doc concernant les triggers. Bonne lecture.
Marsh Posté le 17-06-2008 à 13:06:38
Je suis tombé sur une fonction assez interessante: MERGE. Je pense qu'il serait en fait plus rapide que je remplisse une table temporaire avec SQL*LOADER sans avoir a declencher de trigger et apres un job je fais un Merge. Jsuis egalement tombé sur une autre fonction qui m'a l'air assez interessante: MINUS pour supprimer les employes virés.
Marsh Posté le 17-06-2008 à 19:37:42
ce n'est pas impossible avec un trigger. je pense que tu as simplement pas bien compris son fonctionnement.
Marsh Posté le 17-06-2008 à 20:36:12
+1 avec moi23372, ceci n'a rien à faire dans un trigger.
Marsh Posté le 17-06-2008 à 20:43:51
cervantes a écrit : Il faut bien pouvoir faire le test si ma ligne est un nouvel employé ou non. Si je le fais pas dans mon trigger ou le faire. Je doute pas un instant que mon trigger est nul, c'est le premier que j'ecris. |
dans le code client ou à la rigueur dans une procédure stockée. un trigger permet de réaliser des opérations sur une table en fonction d'évenements arrivant sur d'autres tables, il ne sert pas de remplaçant à if....else ou à switch....case
Marsh Posté le 28-08-2008 à 16:56:03
[quotemsg=1747140,1,8513]Bonjour,
j'ai besoin d'aide pour mon trigger sous Oracle 10g.
Je recupére des données (information d'employé) d'un fichier csv grâce à SQL*Loader que je dois mettre dans une table t_cedd_main. Je souhaiterais avec mon trigger inserer ou mettre a jour les lignes de ma tables suivant s'il y a de nouveaux employés dans le fichier csv ou bien des données modifiée
##############################################
Il existe deux types de triggers.
STATEMENT (DÉFAUT)
EXÉCUTÉ 1 FOIS
NE PERMET PAS DE TRAVAILLER DANS LE TRIGGER POUR CHAQUE TUPLE SUR LES ANCIENNES VALEURS ET LES NOUVELLES VALEURS
ROW (FOR EACH ROW)
EXÉCUTÉ AUTANT DE FOIS QUE DE TUPLES TOUCHÉS PAR LA MAJ
PERMET DE TRAVAILLER DANS LE TRIGGER SUR CHAQUE TUPLE MIS À JOUR
(ANCIENNES ET NOUVELLES VALEURS)
CONTRAINTES DANS LE PL / SQL
MAIS NE PERMET PAS DE MANIPULER LA TABLE SU LAQUELLE EST POSER LE TRIGGER, ON PEUT UNIQUEMENT MODIFIER LES DONNEES new. En cas de BEFORE
EXEMLE:
- solution avec un « STATEMENT TRIGGER »
On laisse s’effectuer d’abord toutes les mises à jour et on vérifie après coup que celles-ci n’engendrent pas la présence de plus d’un président.
*/
create or replace trigger check_president1
after update of job or insert on emp
declare
nbpresident number(2,0);
begin
select count (*) into nbpresident from emp where job = PRESIDENT';
if nbpresident > 1 then
raise_application_error ( -20002, 'IL NE PEUT Y AVOIR PLUS D UN PRESIDENT');
end if;
end;
/
- solution avec un « FOR EACH ROW TRIGGER »
On ne peut dans le PL /SQL d’un FOR EACH ROW TRIGGER faire de SELECT sur la table sur laquelle ce trigger est défini. La solution est donc plus complexe et doit faire intervenir une copie (partielle),table miroir de la table initiale sur laquelle la mise à jour est propagée.
*/
drop table empbis ;
create table empbis as select empno, job, mgr from emp ;
create or replace trigger propage
after delete or update or insert on emp
for each row
begin
if inserting then
insert into empbis values (:new.empno, :new.job,:new.mgr);
elsif deleting then
delete from empbis where empno = ld.empno;
elsif updating then
update empbis set job= :new.job,mgr = :new.mgr where empno =:old.empno;
end if;
end ;
/
/*
Si tout se passe bien dans les mises à jour de la table emp , ces mises à jour seront automatiquement transférées dans empbis.
Il suffit maintenant de poser un trigger en before sur emp qui reportera le select sur la table empbis.
*/
drop trigger check_president1 ;
create or replace trigger check_president2
before update of job or insert on emp
for each row
when (new.job = 'PRESIDENT')
declare
nbpresident number(2,0);
begin
select count (*) into nbpresident from empbis where job = 'PRESIDENT';
if nbpresident > 0 then
raise_application_error ( -20002, 'IL NE PEUT Y AVOIR PLUS D UN PRESIDENT');
end if;
end;
/*
On peut bien sûr envisager d’ autres combinaisons d’évènements et de timing de « FOR EACH ROW TRIGGER ».
Noter que le test sur nbpresident a changé !
j'espere que ca va t'aidé
Marsh Posté le 16-06-2008 à 18:15:19
Bonjour,
j'ai besoin d'aide pour mon trigger sous Oracle 10g.
Je recupére des données (information d'employé) d'un fichier csv grâce à SQL*Loader que je dois mettre dans une table t_cedd_main. Je souhaiterais avec mon trigger inserer ou mettre a jour les lignes de ma tables suivant s'il y a de nouveaux employés dans le fichier csv ou bien des données modifiées.
Voici ce que j'ai fait pour l'instant:
Le probleme de ce trigger c'Est ce que j'ai une exception ORA-04091 TABLE IS MUTATING. D'apres ce que jai pu trouvé sur google, le probleme viendrait que j'ai un trigger de niveau ligne sur ma table t_cedd_main et qu'a l'interieur de ce trigger j'ai un SELECT. Or vu que je voudrait juste ajouter les nouveaux employés et mettre a jour les nouveaux, je ne vois pas du tout comment faire autrement. Je ne peux pas me permettre de vider toute la table et remettre tout a chaque fois car ce trigger devra etre executer tous les jours.
Toutes aides seraient la bienvenue.
A+
Message édité par cervantes le 16-06-2008 à 18:16:01