[RESOLU] MYSQL: Procedure stockée, programmateur d'evenement

Mammouth du PHP | 504 Messages

25 juin 2014, 09:44

Bonjour a tous,

J'ai une table d'événements classé par ville. Pour effectuer la mise a jour des événements (évenements en cours et événements en cours), je lance un cron tous les jours a 00h30. Ce dernier a plusieurs taches:
Pour accélerer le temps de réponse du serveur, je stocke dans une table cache_event les résultats calculés (les 6 prochains événements en cours ou a venir).
Donc, mon cron a pour tache de:
1/ effacer les données dans la table cache_city_evt
2/ Sortir les événements en cours ou a venir dans la limite de 6 et ce pour chaque ville
3/ Inserer ces données dans la table cache_event

Mon script actuel etant en php, et etant recurrent, au vu du nombre de ville et d'événement, je souhaite savoir si je peux faire cette tache en utilisant le programmateur d'évenement mysql.

J'ai lu pas mal de doc, mais je ne trouve que des update ou des actions simples comme tutos.

Voici en gros mon script php:
//Selection de la ville
$requete = "SELECT id, Code_ville FROM table_ville WHERE Code_ville NOT LIKE ''";
$resultat = mysql_query($requete);

while ($blog=mysql_fetch_array($resultat,MYSQL_ASSOC)) {
$i = 0;

// Selection des evenement en cours ou a venir en fonction de la ville
$events = mysql_query("SELECT event_sale.id as events_id, event_sale.name, DATE(event_sale.validFrom) as start_event, DATE(event_sale.validTo) as end_event
FROM `event_sale`
WHERE (event_sale.mid_place LIKE '".addslashes($blog['Code_ville'])."')
AND ((DATE(event_sale.validFrom) <= DATE (NOW()) AND DATE(event_sale.validTo) >= DATE (NOW()) )
OR (DATE(event_sale.validFrom) >= DATE (NOW()) AND DATE(event_sale.validTo) >= DATE (NOW()) )
AND active='1'
ORDER by event_sale.validTo ASC LIMIT 8");

// stockage des résultats dans un array
while($event = mysql_fetch_array($events)) {
$content['events'][$i]['title_event'] = stripslashes($event['name']);
$content['events'][$i]['start_event'] = $event['start_event'];
$content['events'][$i]['end_event'] = $event['end_event'];
$content['events'][$i]['sortie'] = 'Rsortie-'.$i.'-'.$blog['Code_ville'];
$i++;

//insertion en base de données de chaque résultat
@mysql_query("INSERT INTO `cache_city_evt` (`ref_type`,`name_event`,`type`,`ref_city`,`start_event`,`end_event`
) VALUES (     
'".mysql_real_escape_string($content['events'][0]['sortie'])."',
'".mysql_real_escape_string($content['events'][0]['title_event'])."',
'sortie',
'".mysql_real_escape_string($blog['Code_ville'])."',
'".mysql_real_escape_string($content['events'][0]['start_event'])."',
'".mysql_real_escape_string($content['events'][0]['end_event'])."'
) ON DUPLICATE KEY UPDATE 
`name_event`='".mysql_real_escape_string($content['events'][0]['title_event'])."',
`type`='sortie',
`ref_city`='".mysql_real_escape_string($blog['Code_ville'])."',
`start_event`='".mysql_real_escape_string($content['events'][0]['start_event'])."',
`end_event`='".mysql_real_escape_string($content['events'][0]['end_event'])."'
") or die("Erreur MySQL : ".mysql_error());

...etc...
}
}
Mon soucis est que je ne trouve pas d'exemple sur l'utilisation du programmateur d'evenement pour ce type d'action, est ce possible ?

Merci pour votre aide.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

25 juin 2014, 21:30

salut,

sur le principe tu peu faire
[mysql]
create event testevt on schedule every DAY starts 1403733600
do
maprocedure();
[/mysql]

pour créer un event qui commencera le 26/06/2014 à 0000

après fait gaffe aux procédures avec mysql c'est pas aussi complet que sur d'autre SGBD ;)

un cours sur la chose http://fr.openclassrooms.com/informatiq ... re-stockee

edit :

un exemple de procédure stockée qui fait ce que tu souhaite
[mysql]
delimiter |
create procedure maprocedure()
begin
DECLARE done INT DEFAULT 0;
declare firstname varchar(20);
declare lastname varchar(20);
declare p varchar(20);
declare s varchar(1);
declare c_user cursor for select prenom, nom,pseudo,sexe from users;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

delete from utilisateur;

open c_user;

repeat
fetch c_user into firstname, lastname,p,s;
if done = 0 then
insert into utilisateur (prenom, nom,pseudo,sexe) values(firstname, lastname,p,s);
end if;
UNTIL done
end repeat;

end|

delimiter ;[/mysql]

le principe est la, c'est fonctionnel te reste à tout mettre en oeuvre.
pour info la doc sur les events :
http://dev.mysql.com/doc/refman/5.1/en/events.html
http://dev.mysql.com/doc/refman/5.1/en/ ... ation.html
http://dev.mysql.com/doc/refman/5.1/en/ ... event.html

@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 571 Messages

26 juin 2014, 01:39

si l'objectif final est d’insérer une et une seule ligne(d'après ton code) dans la table cache_city_evt alors les 3 requêtes peuvent se réduire en une seule :insert into ...select.sachant que les 2 premières donnent une requête avec jointure entre la table ville et la table event_sale:

INSERT INTO `cache_city_evt` (`ref_type`,`name_event`,`type`,`ref_city`,`start_event`,`end_event`)
SELECT  events_id, `name`,`type`,ref_city, start_event, end_event FROM
	(
	SELECT event_sale.ref_type as events_id, event_sale.name,event_sale.type,table_ville.ref_city, DATE(event_sale.validFrom) as start_event, DATE(event_sale.validTo) as end_event
	FROM `event_sale`
	JOIN table_ville
	ON table_ville.Code_ville = event_sale.ref_city  --colonnes communes entre les tables table_ville et event_sale
	WHERE ((DATE(event_sale.validFrom) <= DATE (NOW()) AND DATE(event_sale.validTo) >= DATE (NOW()) )
	OR (DATE(event_sale.validFrom) >= DATE (NOW()) AND DATE(event_sale.validTo) >= DATE (NOW()) )
	AND active='1'
	ORDER by event_sale.validTo ASC LIMIT 8
	) as req_event_ville
ON DUPLICATE KEY UPDATE
cache_city_evt.name_event=`name`,
cache_city_evt.type=`type`,
cache_city_evt.ref_city=ref_city,
cache_city_evt.start_event=start_event,
cache_city_evt.end_event=end_event;
les mêmes champs qui sont dans insert into doivent être présents dans le select.
tu peux exécuter la requête par la suite dans le corps de la procédure

Mammouth du PHP | 504 Messages

26 juin 2014, 09:17

Bonjour,

suite à un probléme de connexion, j'ai pas pu bosser sur ça hier.

@yann18: non, en fait j'insère 6 lignes.

Le ...etc... correspond à la suite et fin du code, je repete ma requete insert sur les 5 autres sorties de tableau.

@moogli, je bosse dessus aujourd'hui, je vais essayer avec un jeu de données.

Merci a vous deux.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

26 juin 2014, 14:52

de rien,

l'exemple de yann18 est aussi utilisable a partir du moment ou le select fournit les colonnes qui vont bien pour l'insert (c'est surement même ma façon la plus "optimisée").
si ce n'est pas le cas il faut que tu passe par un procédure stockée afin de personnaliser au mieux la sélection.

c'est très puissant bien que relativement limité sur mysql.
Attention a la version de mysql que tu utilise, perso j'ai testé sur une 5.7.


@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 504 Messages

26 juin 2014, 16:47

Re,

En fait sur la requete, je me compliquais un peu la vie, etant donné que mes données s'efface tous les jours, j'avais pas besoin d'etre aussi précis sur la ville notament (les données sont tagués par ville à l'origine) et c'est juste une table de cache pour que améliorer la performance.

J'ai donc utiliser la requete de yann qui me reste plus qu'a mettre en evénément quotidien.