Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/11/2006, 12h23   #1
Futur Membre du Club
 
Avatar de apoingsfermes
 
Inscription : février 2006
Messages : 54
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 54
Points : 18
Points : 18
Par défaut Execution automatique de scripts sur insertion ?

Bonjour,

Je voudrais pouvoir exécuter des tâches plus ou moins complexes, automatiquement, à l'insertion dans une table MySql.

En fait je veux faire deux choses:

- quand une nouvelle ligne est insérée dans une table, la copier automatiquement dans une autre table qui a le même schéma. j'ai essayé avec un trigger, ça nemarche pas : on ne peut pas nommer des tables dans un trigger. La copie doit être immédiate, c'est pour du reporting en temps réel.
- quand une nouvelle ligne est insérée dans une table, et sous certaines conditions sur les valeurs de la ligne, exécuter un script qui envoie un mail avec des paramètres extraits de la ligne insérée. Encore une fois, ça doit être en temps réel. Je ne crois pas qu'un trigger puisse faire l'affaire, vu qu'on ne peut pas appeler CALL dans le corps d'un trigger.

Peut-être y-a-t'il un équivalent de cron dans MySql ?

Sinon je ne vois absolument pas comment faire. (N.B. Je ne maitrise pas le moment ou les lignes sont rajoutées dans la table en question).

Merci pour vos suggestions
apoingsfermes est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2006, 16h51   #2
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
Citation:
Envoyé par apoingsfermes
- quand une nouvelle ligne est insérée dans une table, la copier automatiquement dans une autre table qui a le même schéma. j'ai essayé avec un trigger, ça nemarche pas : on ne peut pas nommer des tables dans un trigger. La copie doit être immédiate, c'est pour du reporting en temps réel.
Cela devrait être possible. C'est probablement une question de syntaxe.

Citation:
Envoyé par apoingsfermes
- quand une nouvelle ligne est insérée dans une table, et sous certaines conditions sur les valeurs de la ligne, exécuter un script qui envoie un mail avec des paramètres extraits de la ligne insérée. Encore une fois, ça doit être en temps réel. Je ne crois pas qu'un trigger puisse faire l'affaire, vu qu'on ne peut pas appeler CALL dans le corps d'un trigger.
Je ne sais pas si c'est possible. Dans le pire des cas, le trigger pourrait insérer une ligne dans une table 'mail' qu'un CRON, un vrai, viendrait interroger à intervalle régulier pour envoyer les mails et marquer/retirer les lignes correspondantes de la table. Les mails ayant une vitesse non garantie, les interrogations peuvent être modérément fréquences pour ne pas charger le serveur (et un select ce n'est pas grand chose).

C'est un pis aller, si qqn voit comment faire ça depuis mysql...
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2006, 17h56   #3
Futur Membre du Club
 
Avatar de apoingsfermes
 
Inscription : février 2006
Messages : 54
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 54
Points : 18
Points : 18
Citation:
C'est probablement une question de syntaxe.
J'en doute: il est bien spécifié dans la référence (j'ai la derniere version stable de MySQL, 5.0.X), que, je cite: "Le déclencheur ne peut pas faire référence directe aux tables par leur nom, y copmris (sic) la table à laquelle il est associé".
Pour en avoir le coeur net, j'ai essayé de créer le trigger suivant :
Code :
1
2
3
4
5
6
7
 
CREATE TRIGGER fillmytable
after INSERT ON firsttable
FOR each row
begin
INSERT INTO secondtable SELECT new.* WHERE new.myfield LIKE 'fieldValue%';
end;
et ça n'a pas marché: Syntax error near '' (42000) : ça aide

Pour le deuxième problème, un CRON pourrait marcher: Dans la table que le script programmé surveille, il y a un champ 'DateTime' donnant la date d'enregistrement de chaque ligne de la table. je pourrais donc surveiller les lignes rajoutées depuis la dernière fois que j'ai exécuté mon script, et effectuer les actions qui s'imposent.
Pb : comme ça doit être en temps réel, le script doit tourner au moins toutes les minutes: ç'est pas bon pour la charge serveur.
apoingsfermes est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2006, 18h39   #4
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
J'ai une 5.0.27-community-nt et je peux tout à fait faire :
Code :
1
2
3
4
5
6
7
8
9
 
CREATE TRIGGER fillmytable
AFTER INSERT ON mytable
    FOR EACH ROW BEGIN
        INSERT INTO mytable2 VALUES (new.champ1, new.champ2, ...);
    END;
|
 
DELIMITER ;
Par contre il faut être prudent un trigger peut planter lors de son déclanchement pour un pb de syntaxe alors que sa définition a été acceptée (ça m'est arrivé lors du test de la première version de celui ci). Il semble impossible de ne pas lister tous les champs.

Citation:
Prior to MySQL 5.0.10, triggers cannot contain direct references to tables by name.
La doc en anglais est bien plus à jour.

Citation:
Pb : comme ça doit être en temps réel, le script doit tourner au moins toutes les minutes: ç'est pas bon pour la charge serveur.
C'est vrai que suivant le volume... ou alors un script perl ou quoi que ce soit qui vienne vérifier de temps à autre pour ne pas le relancer et conserver la même connexion. Si en plus c'est toutes les minutes ça limite déjà pas mal la charge.
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 11h29   #5
Futur Membre du Club
 
Avatar de apoingsfermes
 
Inscription : février 2006
Messages : 54
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 54
Points : 18
Points : 18
Allons bon, j'ai aussi la version 5.0.27, mais si je tente de créer un trigger comme celui que tu donnes en exemple, j'ai l'erreur suivante:
Code :
ERROR 1064 (42000) You have an error IN your SQL syntax; CHECK FOR the manual [...] TO USE near '' at line 1
Si j'essaie ce trigger:
Code :
1
2
3
4
5
6
7
8
 
delimiter |
CREATE TRIGGER fillmytable
after INSERT ON mytable
FOR each row begin
INSERT INTO mytable2 SELECT new.*;
end;
|
, j'ai exactement la même erreur.

Ceci est bizarre : un "show databases;" marche bien, mais un "show triggers;" fait planter la connection, et retourne:
Code :
ERROR 2013 (HY000): Lost connection TO MySQL server during query
Auparavent, j'avais réussi à créer un trigger, qui plantait à l'exécution. Puis je l'ai droppé, et maintenant j'ai cette erreur et je n'arrive même plus à recréer ce trigger.

Il faut que je réinstalle tout ?
apoingsfermes est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 13h13   #6
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
Citation:
Envoyé par apoingsfermes
Code :
1
2
3
4
5
6
7
8
 
delimiter |
CREATE TRIGGER fillmytable
after INSERT ON mytable
FOR each row begin
INSERT INTO mytable2 SELECT new.*;
end;
|
Pour celui-ci c'est normal, la syntaxe de l'insert est invalide.
Code :
INSERT INTO mytable2 SELECT * FROM mytable WHERE mytable.id=new.id
serait plus conforme mais je ne sais pas si ça sera accepté (et ça fait toujours un select de plus).

L'idéal mais le plus contraignant à écrire reste :
Code :
INSERT INTO mytable2 VALUES (new.id, new.champ1, new.champ2);
Citation:
Envoyé par apoingsfermes
Ceci est bizarre : un "show databases;" marche bien, mais un "show triggers;" fait planter la connection, et retourne:
Code :
ERROR 2013 (HY000): Lost connection TO MySQL server during query
Auparavent, j'avais réussi à créer un trigger, qui plantait à l'exécution. Puis je l'ai droppé, et maintenant j'ai cette erreur et je n'arrive même plus à recréer ce trigger.

Il faut que je réinstalle tout ?
Etrange... Peut-être retenter un 'DROP TRIGGER' sur les triggers qiui ont été créés par prudence, essayer un 'DROP DATABASE' et/ou redémarrer le serveur... J'ai peu l'expérience des triggers et je n'ai jamais vu ça.
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 19h20   #7
Futur Membre du Club
 
Avatar de apoingsfermes
 
Inscription : février 2006
Messages : 54
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 54
Points : 18
Points : 18
Merci pour ta patience, Sivrît, mais moi je la perds, la mienne...

J'ai essayé les deux variantes de triggers que tu proposes. J'arrive à les déclarer, mais sur des tables de tests différentes de celles sur lesquelles je m'acharne depuis quelques temps. Passons...
Ces triggers plantent toujours à l'exécution, avec toujours la même erreur: il ne reconnait pas la table "new" !! :
"mabase.new is not known"

Pour couronner le tout, je viens de m'apercevoir que mon serveur SQL de prod est une version 4.X
Conclusion :je laisse tomber les triggers sous MySql; je ferai des scripts qui tournent souvent; trop souvent, mais bon...
apoingsfermes est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/11/2006, 17h08   #8
Futur Membre du Club
 
Avatar de apoingsfermes
 
Inscription : février 2006
Messages : 54
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 54
Points : 18
Points : 18
Par défaut La solution !

J'ai trouvé la solution !!
Il ne reconnait pas 'new', mais il reconnait 'NEW' !
Donc il faut mettre NEW en majuscules dans le trigger, et ça roule
Je croyais que mysql était totalement insensible à la casse...
T'aing, chius content
apoingsfermes est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/11/2006, 17h49   #9
Membre Expert
 
Avatar de Sivrît
 
Inscription : février 2006
Messages : 953
Détails du profil
Informations personnelles :
Âge : 30
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2006
Messages : 953
Points : 1 189
Points : 1 189
Insensible à la casse... sauf pour les noms de tables (suivant réglage, la valeur par défaut dépendant de l'OS). Inutile de dire que j'ai fait mes tests sous windows je crois

Donc le "new" des triggers est considéré comme une table et non un mot clef... intéressant.

Bien, content pour toi !
Sivrît est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h20.


 
 
 
 
Partenaires

Hébergement Web