Procédure stockée

Résolu/Fermé
Utilisateur anonyme - 14 avril 2010 à 17:47
 Utilisateur anonyme - 15 avril 2010 à 14:49
Bonjour

Je suis en train de regarder comment faire une procédure stockée sur MySQL...

Contexte :

table md_visites_jour qui contient 4 champs INT : jour,mois,annee,nombre

En fait à chaque visite d'un membre sur mon site je veux incrémenter la variable membre, et mon plus gros problème se situe au niveau de la création de l'enregistrement pour chaque jour. En effet, le premier visiteur du jour, il n'y a pas encore l'entrée du jour dans cette table, il faut donc qu'elle soit crée pour que les visites puissent être comptabilisée

voilà ce que j'ai fais pour l'instant (qui marche pas du tout mais qui compile ^^)


CREATE PROCEDURE incrementVisit(IN pday INT(10),IN pmonth INT(10),IN pyear INT(10))
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000', SQLEXCEPTION 
BEGIN
INSERT INTO md_visites_jour SET nombre=1, jour=pday, mois=pmonth, annee=pyear;
END;
UPDATE md_visites_jour SET nombre=nombre+1 WHERE jour=pday AND mois=pmonth AND annee=pyear;
END|


la requête s'exécute bien (sans erreur), mais l'enregistrement lié au jour n'es pas créé
si l'enregistrement pour le jour existe déjà, là aucun problème le champ nombre est bien incrémenté


sinon n'y a t il pas la possibilité que mysql recup lui même quel jour on est plutôt que de lui passer en paramètre ?


merci

6 réponses

ahhh ok ok ok ok d'accord !

sache qu'un update qui met 0 (ZERO) ligne à jour ne déclenche pas d'erreur !

donc si ta gestion d'erreur est en place pour gérer le fait qu'aucune ligne n'est mise à jour par ton update, elle ne servira jamais à ça (elle risque simplement de te masquer d'autres erreurs).

si tu as besoin de savoir combien de lignes ont été impactées par la dernière requête, tu dois avoir un moyen simple de le déterminer (je te laisser chercher pour MySQL, en oracle c'est sql%ROWCOUNT)
...et dans ta procédure, si tu découvres que 0 ligne a été mise à jour par ton update, c'est alors le moment de balancer ton insert

pour ma part, je pense que cette fonction (ou pseudo-colonne ou attribut) existe car, depuis un interpréteur MySQL, le nombre de lignes impactées par la dernière requête est toujours annoncé après le résultat.
1
Salut

Je suis pas très doué en MySQL (et donc encore moins dans ses procédures stockées).
Ce qui me chagrine, c'est ce INSERT INTO table SET colonne=expression.
Est-ce du SQL valide pour MySQL ?

pour ma part, j'aurais plutot fait
-- 1. récupérer s'il existe déjà un compteur pour la journée
SELECT count(1)
  INTO compteur
  FROM md_visites_jour
  WHERE jour=pday
  AND mois=pmonth
  AND annee=pyear;
-- 2. si oui alors update si non lors insert
IF compteur > 0 THEN
  UPDATE md_visites_jour
    SET nombre = nombre + 1
    WHERE jour=pday
    AND mois=pmonth
    AND annee=pyear;
ELSE
  INSERT INTO md_visites_jour
    VALUES(1, pday, pmonth, pyear)
END IF

il te reste maintenant à adapter ça à MySQL car
* je sais pas si le select into est valide
* je sais pas si le if est valide
0
Utilisateur anonyme
14 avril 2010 à 21:29
De une j'ai dis que la reqête s'exécutait,
de 2 pourquoi ca serai pas valide ? tu n'a jamais fait un INSERT en sql ? XD
0
euh... en MySQL jamais :-)

mais tu as raison, ne connaissant pas MySQL je n'aurais ptetre pas du chercher à filer un coup de main: "mal savoir est pire qu'ignorer"

Ce qui me laissait penser à une erreur, c'est le DECLARE CONTINUE HANDLER ... que je voyais bien comme un gestionnaire d'exception qui te cache une erreur d'exécution (que je croyais être INSERT INTO... SET... car je connaissais pas cette syntaxe)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
15 avril 2010 à 00:54
ba je me suis basé sur le siteduzero

le declare continue handler c'est la gestion d'erreur lnormalement, et en fait je voulais exploiter ca, car s'il arrive pas à mettre à jour un enregistrement qui existe pas logiquement une erreur est levée, et donc moi je veux la récupérer pour faire l'insertion (au lieu de l'update)

car dans ta solution dans tous les cas 2 requetes sont éxécutée, dans ma solution, dans 99% des cas, une seule requete sera executé, il n'y aura qu'une seule fois par jour où 2 requete seront executées

tout ceci dans un but d'optimisation maximale ^^


enfin c'est quand même sympa d'essayer de m'aider ;)
0
ok merci, je vais regarder du coté du rowcount, il me semble avoir vu une fonction php-mysql en rapport avec ca donc c'est que ca existe ^^


EDIT voilà réussi \o/
CREATE PROCEDURE incrementVisit(IN pday INT(10),IN pmonth INT(10),IN pyear INT(10)) 
BEGIN 
DECLARE rowcount INT; 
UPDATE md_visites_jour SET nombre=nombre+1 WHERE jour=pday AND mois=pmonth AND annee=pyear; 
SELECT ROW_COUNT() INTO rowcount; 
IF rowcount= 0 THEN 
INSERT INTO md_visites_jour SET nombre=1, jour=pday, mois=pmonth, annee=pyear; 
END IF; 
END|


Prochaine étape réussir à trouver si mysql connais le joru qu'on est afin de supprimer les paramètres ^^

EDIT2 voilà procédure stockée terminée ^^
CREATE PROCEDURE incrementVisit()
BEGIN
	DECLARE rowcount INT;
        UPDATE md_visites_jour SET nombre=nombre+1 WHERE jour=DAY(NOW()) AND mois=MONTH(NOW()) AND annee=YEAR(NOW());
	SELECT ROW_COUNT() INTO rowcount;
	IF rowcount= 0 THEN
		INSERT INTO md_visites_jour SET nombre=1, jour=DAY(NOW()), mois=MONTH(NOW()), annee=YEAR(NOW());
	END IF;
END|


Lapinkiller, Développeur web & Java.
"Ne prend pas ta vie à 2 mains, gardes en une de libre pour te rattraper au cas où tu tomberais..." (Lapinkiller)
0