Le trigger m'a tuer

Le trigger m'a tuer - SQL/NoSQL - Programmation

Marsh Posté le 30-08-2011 à 12:37:48    

Bonjour à tous,
 
J'ai modifié mon trigger before delete jusqu'à en plus pouvoir... mais rien n'y fait il refuse de fonctionner correctement.  
 
Grosso modo j'ai une table 'news', une table 'usager' et une table 'historique', quand j'efface une news je souhaite que mon trigger efface automatiquement les lignes correspondant à cette news dans ma table 'historique'.
 
http://i68.photobucket.com/albums/i7/Anatal/historique_trigger.gif
 
J'ai essayé de modifier mon trigger, avec ou sans jointure, mais le résultat est toujours le même.
Message d'erreur:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER deleteNewsHisto BEFORE DELETE ON news FOR EACH ROW BEGIN
DELETE FRO' at line 1

 
Voici les contraintes de mes tables:

Code :
  1. -- Contrainte pour la table 'news'
  2. ALTER TABLE `news`
  3.   ADD CONSTRAINT `FK_news_usager` FOREIGN KEY (`idusager`) REFERENCES `usager` (`idusager`);
  4. -- Contraintes pour la table `historique`
  5. ALTER TABLE `historique`
  6.   ADD CONSTRAINT `FK_histo_adresse` FOREIGN KEY (`idadresse`) REFERENCES `adresse` (`idadresse`),
  7.   ADD CONSTRAINT `FK_histo_annuaire` FOREIGN KEY (`idannuaire`) REFERENCES `annuaire` (`idannuaire`),
  8.   ADD CONSTRAINT `FK_histo_catref` FOREIGN KEY (`idcatref`) REFERENCES `catref` (`idcatref`),
  9.   ADD CONSTRAINT `FK_histo_contact` FOREIGN KEY (`idcontact`) REFERENCES `contact` (`idcontact`),
  10.   ADD CONSTRAINT `FK_histo_ficheref` FOREIGN KEY (`idficheref`) REFERENCES `ficheref` (`idficheref`),
  11.   ADD CONSTRAINT `FK_histo_missionref` FOREIGN KEY (`idmissionref`) REFERENCES `missionref` (`idmissionref`),
  12.   ADD CONSTRAINT `FK_histo_news` FOREIGN KEY (`idnews`) REFERENCES `news` (`idnews`),
  13.   ADD CONSTRAINT `FK_histo_usager` FOREIGN KEY (`idmodificateur`) REFERENCES `usager` (`idusager`);


 
La dernière version de mon Trigger est celle-ci :

Code :
  1. DROP TRIGGER IF EXISTS deleteNewsHisto;
  2. DELIMITER //
  3. CREATE TRIGGER deleteNewsHisto
  4. BEFORE DELETE ON news
  5. FOR EACH ROW
  6. BEGIN
  7. DELETE FROM historique
  8. WHERE historique.idnews = news.OLD.idnews;
  9. END
  10. //
  11. DELIMITER ;


 
Si vous voyez ce qui ne va pas, je vous écoute d'une oreille attentive.
 
Question supplémentaire: si je veux ajouter un delete à ce trigger pour qu'il efface en plus les occurences liées à ma news dans une autre table, est-ce possible? (je veux dire sans écrire un autre trigger mais en ajoutant seulement cette instruction à mon trigger existant).


---------------
Quand vous demandez sur un forum comment changer un pneu de voiture peu de gens vous répondent. Et ceux qui le font vous expliquent généralement comment rouler sur 3 roues.
Reply

Marsh Posté le 30-08-2011 à 12:37:48   

Reply

Marsh Posté le 30-08-2011 à 12:57:45    

Les triggers c'est le mal.
Utilise plutot une deuxieme query dans ton application pour faire le nettoyage, ou mieux encore, ne l'efface pas et fais une maintenance qui tourne toutes les x minutes/heures (ca depend de la quantité) pour effacer l'historique orpheline.
 
Avec la maintenance tu acceleres tes delete et tu peux deporter le nettoyage a un moment ou il y a moins d'utilisateurs.

Reply

Marsh Posté le 30-08-2011 à 14:24:57    

La syntaxe de ton trigger semble correcte, si ce n'est que le delimiteur n'est pas forcément celui que j'aurais choisi.
Essaye de le changer pour voir...
Comment exécutes-tu la requête de création?
 

Oliiii a écrit :

Les triggers c'est le mal.


source?


---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Marsh Posté le 30-08-2011 à 23:15:40    

Et rajouter un simple "ON DELETE CASCADE" sur la forward key, ce ne serait pas plus simple :??:  
(certes, ça n'explique pas le problème [:figti] )


---------------
Doucement le matin, pas trop vite le soir.
Reply

Marsh Posté le 31-08-2011 à 08:09:14    


Mon experience avec sql et une armée de dev (1000+) avec des idées plus originales les unes que les autres.
Le bon sens aussi...
 
Les triggers ajoutent un niveau de traitment pratiquement toujours caché et en general qui ne tiens pas compte de l'impact sur les perfs.
Ce qui est fait dans un trigger peut dans pratiquement tout les cas etre fait en dehors de maniere plus claire, plus souple et plus rapide.
L'utilisation correcte d'un trigger est extremenent rare et cantoné a des cas tres particulier.
 
Les triggers, avec les boucles dans les procedures et toute une serie de choses sont des indications d'un manque de connaissance en developpement DB, d'une mauvais analysise du projet ou d'un mauvais design de la DB...

Reply

Marsh Posté le 31-08-2011 à 10:11:56    

+1 j'approuve entièrement ce que dit Oliiii, et ça fait plaisir de lire une critique des triggers, parce que c'est une plaie.

Reply

Marsh Posté le 31-08-2011 à 10:41:48    

Je suis aussi assez d'accord avec le point de vue de Oliiii sur les triggers. Cependant, j'en comprends aussi l'utilité. A la base, c'est toujours une question d'intégrité des données. Si un utilisateur commence à bidouiller les données sans passer par l'appli et que les traitement d'intégrité sont fait par l'appli, la BD va être mise à mal. Alors qu'avec les triggers, non ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 31-08-2011 à 13:16:14    

SV_LVH a écrit :


La dernière version de mon Trigger est celle-ci :

Code :
  1. DROP TRIGGER IF EXISTS deleteNewsHisto;
  2. DELIMITER //
  3. CREATE TRIGGER deleteNewsHisto
  4. BEFORE DELETE ON news
  5. FOR EACH ROW
  6. BEGIN
  7. DELETE FROM historique
  8. WHERE historique.idnews = news.OLD.idnews;
  9. END
  10. //
  11. DELIMITER ;



 
news.OLD.idnews à remplacer par OLD.idnews : le moteur MySQL sait déjà que OLD est un enregistrement de la table news.
 

Oliiii a écrit :


Les triggers ajoutent un niveau de traitment pratiquement toujours caché et en general qui ne tiens pas compte de l'impact sur les perfs.
Ce qui est fait dans un trigger peut dans pratiquement tout les cas etre fait en dehors de maniere plus claire, plus souple et plus rapide.
L'utilisation correcte d'un trigger est extremenent rare et cantoné a des cas tres particulier.


 
Sur le principe des problèmes de perfs, je suis globalement d'accord. D'ailleurs hier, j'ai tué une base de données MySQL pendant 20 minutes, en faisant un UPDATE d'une seule table qui m'a déclenché une ribambelle de triggers autant de fois qu'il y avait d'enregistrements dans la table, chaque triggers faisant individuellement des SELECT, des INSERT ou des UPDATE.

Reply

Marsh Posté le 31-08-2011 à 15:22:50    

rufo a écrit :

Je suis aussi assez d'accord avec le point de vue de Oliiii sur les triggers. Cependant, j'en comprends aussi l'utilité. A la base, c'est toujours une question d'intégrité des données. Si un utilisateur commence à bidouiller les données sans passer par l'appli et que les traitement d'intégrité sont fait par l'appli, la BD va être mise à mal. Alors qu'avec les triggers, non ;)


 
Dans ce cas la c'est le design de la DB qui a un probleme :)
L'integrite peut etre assurée par la DB si les foreign keys sont utilisées. N'importe quel utilisateur/appli devra ajouter/effacer les enregistrements dans le bon ordre et l'integrité sera toujours correcte. Le role du SGBD c'est de proteger l'integrité des données, pas d'en faciliter les delete :)
 
Un des rare cas ou les triggers sont difficil a eviter c'est pour de l'audit qui doit etre fait independement de l'appli (audit legal, trouvage de crétin qui delete ce qu'il ne devrai pas, etc ...). Et encore ca depend des SGBD, dans SQL et Oracle il y a des process tout fait qui peuvent faire ca avec un minimum d'impact et de maniere transparente.

Reply

Marsh Posté le 31-08-2011 à 21:12:45    

je suis aussi d'accord sur les commentaires des triggers ...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed